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;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
BShan
  • 3
  • 2
  • 2
    You have the *argument* `ret` and then you also define the *local variable* `ret`. Remove one of them. – Some programmer dude May 16 '20 at 13:52
  • regarding: `int* ret=(int*)malloc(sizeof(int)*2);` 1) be sure to have the statement: `#include ` 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`. – user3629249 May 17 '20 at 14:53
  • regarding the statement: `for(i=0;i – user3629249 May 17 '20 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 – user3629249 May 17 '20 at 15:31
  • @BShan: you can accept one of the answers y clicking on the grey checkmark below its score. – chqrlie May 19 '20 at 20:38

4 Answers4

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;
}
P.P
  • 117,907
  • 20
  • 175
  • 238
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);
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);

simran-ahuja
  • 165
  • 4
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;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189