【问题标题】:How to malloc this array in this function and return the array to the main function?如何在这个函数中malloc这个数组并将数组返回给主函数?
【发布时间】:2020-05-16 13:49:57
【问题描述】:

下面是一个取自 leetcode 的问题:Two Sum 问题,其中一个特定的目标值应该从数组中任意 2 个元素的和得到,并且两个元素的索引应该是存储在返回数组中,应该分配并返回。

'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;
}

【问题讨论】:

  • 您有 参数 ret,然后您还定义了 局部变量 ret。删除其中一个。
  • 关于:int* ret=(int*)malloc(sizeof(int)*2); 1) 一定要声明:#include &lt;stdlib.h&gt; 2) 返回的类型是void*,可以分配给任何指针。强制转换只会使代码混乱并且容易出错。建议删除该演员表。 3) 始终检查 (!=NULL) 返回值以确保操作成功。如果不成功 (==NULL) 则调用perror( "Your error message" ); 将您的错误消息和系统认为发生错误的文本原因输出到stderr
  • 关于语句:for(i=0;i&lt;numsSize;i++) 建议将此for() 循环限制为:for( i=0; i&lt; (numsSize-1); i++ ),以避免变量j 等于numsSize 进行一次内部循环迭代。 j 的此类值导致 nums[j] 访问数组末尾之外的 nums[] 导致未定义的行为(并且可能是段错误事件)
  • OT:关于:int i,j; 这是将这些变量的“范围”设置为file scope。但是,良好的编程习惯是限制变量的“范围”。建议删除该行并修改:for(i=0;i&lt;numsSize;i++)for( int i=0; i&lt;numsSize; i++ )。类似的考虑适用于声明:for(j=i+1;j&lt;numsSize;j++)。此外,请注意使用适当的水平间距以提高可读性。编译器并不关心,但人类确实关心可读性。
  • @BShan:点击分数下方的灰色复选标记,您可以接受其中一个答案。

标签: c arrays malloc


【解决方案1】:

错误是因为你在twoSum函数中声明了两次。

参数ret 在任何情况下都是一个红鲱鱼,因为你不能分配(即不能通过传递的指针返回)调用者可以使用的分配指针 - 因为参数是按值传递的在 C 中(有关这方面的更多信息,请参阅Changing address contained by pointer using 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;
}

【讨论】:

    【解决方案2】:

    如前所述,您有两个ret 声明。参数列表中的一次

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

    另一个在:

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

    除了@usr 的建议之外,还有另一种可能的方法。

    如果你想在调用者中提供一个指针,函数twoSum中分配的动态内存将指向该指针,将ret声明为int**并取消引用ret以在调用者中分配指针分配内存的地址。

    不要忘记检查从malloc()返回的指针是否为NULL,以检查分配是否成功。

    malloc() 返回的指针不需要强制转换。

    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;
    }
    

    然后这样称呼它:

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

    【讨论】:

    • 关于:(*ret)[0] = i; (*ret)[1] = i; 这应该是:(*ret)[0] = i; (*ret)[1] = j; 所以设置来自ij 的值
    • @user3629249 嗯。想。已更正。谢谢。
    【解决方案3】:

    ret 将作为函数twoSum 的输入变量。 您在第 2 行重新声明 ret

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

    相反,您应该稍后对其进行分配:

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

    【讨论】:

      【解决方案4】:

      ret 在函数twoSum 中被有效地声明了两次:

      • 作为最后一个参数的名称,类型为int *
      • 作为具有相同类型的局部变量。

      这个错误令人困惑,因为两个声明具有相同的类型,但它仍然是一个错误。

      请注意,函数twoSum 应该只更新它获取指针ret 的数组,并返回1 表示成功,0 表示失败,或其他约定。发布的版本即使找到解决方案也会继续搜索解决方案,并且始终返回ret,即使没有找到解决方案也是如此。调用者无从得知。

      这是修改后的版本:

      /**
       * 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;
      }
      

      【讨论】:

        猜你喜欢
        • 2017-09-06
        • 2015-06-04
        • 2013-03-10
        • 1970-01-01
        • 2014-12-17
        • 1970-01-01
        • 1970-01-01
        • 2020-04-08
        • 1970-01-01
        相关资源
        最近更新 更多