1

The following is a problem taken from leetcode: Two Sum problem, where a specific target value should be achieved from the sum of any 2 elements in the array and the indices of the two elements should be stored in the return array which should be malloced and returned.

I am getting an error as 'ret is redeclared as different kind of symbol'.

/**
  * Note: The returned array must be malloced, assume caller calls free().
 */
int *twoSum(int *nums, int numsSize, int target, int *ret) {
    int i, j;
    int *ret = (int *)malloc(sizeof(int) * 2);
    for (i = 0; i < numsSize; i++) {
        for (j = i + 1; j < numsSize; j++) {
            if (nums[i] + nums[j] == target) {
                ret[0] = i;
                ret[1] = j;
            }
        }
    }
    return ret;
}
5
  • 2
    You have the argument ret and then you also define the local variable ret. Remove one of them. Commented May 16, 2020 at 13:52
  • regarding: int* ret=(int*)malloc(sizeof(int)*2); 1) be sure to have the statement: #include <stdlib.h> 2) the returned type is void* which can be assigned to any pointer. Casting just clutters the code and is error prone. Suggest removing that cast. 3) always check (!=NULL) the returned value to assure the operation was successful. If not successful (==NULL) then call perror( "Your error message" ); to output both your error message and the text reason the system thinks the error occurred to stderr. Commented May 17, 2020 at 14:53
  • regarding the statement: for(i=0;i<numsSize;i++) Suggest limiting this for() loop to: for( i=0; i< (numsSize-1); i++ ) so as to avoid the variable j being equal to numsSize for one iteration of the inner loop. Such a value for j causes nums[j] to access beyond the end of the array nums[] resulting in undefined behavior ( and possibly a seg fault event ) Commented May 17, 2020 at 15:08
  • OT: regarding: int i,j; This is setting the 'scope' of those variables to file scope. However, good programming practice is to limit the 'scope' of variables . Suggest removing that line and modifying: for(i=0;i<numsSize;i++) to for( int i=0; i<numsSize; i++ ). Similar considerations apply to the statement: for(j=i+1;j<numsSize;j++). Also, note the use of appropriate horizontal spacing for readability. The compiler doesn't care but humans do care about readability. Commented May 17, 2020 at 15:31
  • @BShan: you can accept one of the answers y clicking on the grey checkmark below its score. Commented May 19, 2020 at 20:38

4 Answers 4

1

The error is because you have declared twice in twoSum function.

The argument ret is a red-herring in any case as you can't assign (i.e. can't return via the passed pointer) an allocated pointer to it that the caller can use - because arguments are passed by value in C (see Changing address contained by pointer using function for more info on this). Since you're returning the pointer, you just need to remove the argument and rewrite your function.

int *twoSum(int *nums, int numsSize, int target)
{
    int i, j;
    int *ret = malloc(sizeof(int) * 2);
    if (!ret) return NULL;

    /* In case, no such indexes are found. */
    ret[0] = -1;
    ret[1] = -1;

    for(i = 0;i < numsSize; i++)
    {
        for(j = i+1; j < numsSize; j++)
        {
            if(nums[i] + nums[j] == target)
            {
                ret[0] = i;
                ret[1] = j;
            }
        }
    }
    return ret;
}
Sign up to request clarification or add additional context in comments.

Comments

1

As already said you have two declarations of ret. One time in the parameter list

int* twoSum(int* nums, int numsSize, int target, int* ret)

and another at:

int *ret = malloc(sizeof(int)*2);

Beside the suggestion from @usr there is another possible way.

If you want to provide a pointer in the caller to which the dynamic memory allocated in the function twoSum shall point to, declare ret as int** and dereference ret to assign the pointer in the caller by the address of the allocated memory.

Don´t forget to check if the allocation were successful by checking the returned pointer from malloc() for NULL.

The returned pointer from malloc() do not need to be casted.

void twoSum (int* nums, int numsSize, int target, int** ret){

     int i,j;
     *ret = malloc(sizeof(int)*2);

     if (*ret == NULL)
     {
         fputs("Allocation failed!",stderr);
         exit(1);     
     }

     for(i = 0; i < numsSize; i++)
     {
         for(j = i + 1; j < numsSize; j++)
         {
             if(nums[i] + nums[j] == target)
             {
                 (*ret)[0] = i;
                 (*ret)[1] = j;
             }
         }
     }
     return;
}

And call it like:

twoSum(nums_ptr, numsSize, target, &ptr);

2 Comments

regarding: (*ret)[0] = i; (*ret)[1] = i; This should be: (*ret)[0] = i; (*ret)[1] = j; so setting values from both i and j
@user3629249 Uhhh. Thinko. Corrected. Thank you.
0

ret is coming as an input variable to the function twoSum. You are redeclaring ret in line number 2 with:

int* ret=(int*)malloc(sizeof(int)*2);

Instead you should just do an assignment to it later:

ret=(int*)malloc(sizeof(int)*2);

Comments

0

ret is effectively declared twice in the function twoSum:

  • as the name of the last argument with type int *
  • as a local variable with the same type.

The error is confusing as both declarations have the same type, but it is nevertheless an error.

Note that the function twoSum should just update the array to which it gets the pointer ret and return 1 for success and 0 for failure, or some other convention. The posted version keeps searching for solutions even if it found one and always returns ret, even if no solutions were found. The caller has no way to tell.

Here is a modified version:

/**
 * Note: The caller must pass a pointer to an array of 2 int
 * the return value is 1 if a solution was found, 0 otherwise
 */
int twoSum(int const *nums, int numsSize, int target, int *ret) {
    int i, j;
    for (i = 0; i < numsSize; i++) {
        for (j = i + 1; j < numsSize; j++) {
            if (nums[i] + nums[j] == target) {
                ret[0] = i;
                ret[1] = j;
                return 1;
            }
        }
    }
    return 0;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.