繁体   English   中英

malloc() 无法在 C 中的函数内分配内存

[英]malloc() fails to allocate memory inside a function in C

我想在函数内部动态分配内存。 该函数名为func_1并声明如下:

int func_1(int **destination);

这里的destination是一个指向指针的指针。 这个指针包含我想在函数内部动态分配内存的指针的地址。

函数func_1具有以下代码:

void func_1(int **destination)
{
   *destination = (int*)malloc(sizeof(int) * 10);
   for(int i = 0 ; i < 10 ; i++)
   {
      *destination[i] = i;             //segmentation fault comes HERE
   }    
}

下面是我的main()函数:

int main()
{
   int *pointer;
   func_1(&pointer);
   return 0;
}

当我尝试运行此程序时,出现分段错误 (SIGSEGV) 错误。 我用GDB定位了这个错误的根源,结果发现for循环里面的那一行是这个错误的罪魁祸首。

请注意,一旦函数退出,我希望保留分配给函数内部动态分配内存的值,这就是我传递了要动态分配内存的指针地址的原因。

我想知道:

  • 为什么我收到这个错误?

  • 如何解决这个问题?

感谢帮助 !

[] (数组下标)运算符的优先级为 2

* (取消引用)运算符的优先级为 3

在您的代码中*destination[i]含义与*(destination[i]) 此值未初始化并导致分段错误。

如果您将使用明确的操作优先级(*destination)[i]您将获得预期的结果。

void func_1(int **destination)
{
   *destination = (int*)malloc(sizeof(int) * 10);
   for(int i = 0 ; i < 10 ; i++)
   {
      (*destination)[i] = i;             //no segmentation fault
   }    
}

您可以在此处阅读有关优先级的更多信息

完整代码:

#include <stdio.h>
#include <stdlib.h>

void func_1(int **destination)
{
   *destination = (int*)malloc(sizeof(int) * 10);
   for(int i = 0 ; i < 10 ; i++)
   {
      (*destination)[i] = i;             
   }
}

int main()
{
   int *pointer;
   func_1(&pointer);
   return 0;
}

为什么我收到这个错误?

要覆盖destination分配返回的值的指针代替malloc由指向指针destination指针。

  • 而不是*destination = (int*)malloc(sizeof(int) * 10)你应该输入**destination = malloc(sizeof(int) * 10)
  • 你应该输入(**destination)[i] = i而不是*destination[i] = i (**destination)[i] = i

在 C 中,数组下标运算符[]的优先级高于间接运算符* 除此之外,前者是从左到右关联的,而后者是从右到左关联的

在您的情况下,这意味着您需要输入(**destination)[i] = i; 而不是**destination[i] = i ,因为否则[i]将在**之前被评估,你最终会间接指向一个野指针(这在一般情况下极有可能导致分段错误,在这种情况下绝对肯定) ,因为当i == 0时您正在引用空指针)。


如何解决这个问题?

“让它工作”的解决方法是我上面介绍的方法。

但是,这并没有解决您的代码的根本问题,即它不必要地复杂 使用指向指针的指针很容易出错,应该避免。 事实上,在这种情况下根本不需要使用一个。

以下完全符合您的要求,而没有所有不必要的复杂性:

int* func_1()
{
   int* destination = malloc(sizeof(int) * 10);
   for (int i = 0; i < 10; ++i)
   {
      destination[i] = i;
   }
   return destination;
}
int main()
{
   int* pointer = func_1();
   free(pointer);
   return 0;
}

请注意,一旦函数退出,我希望保留分配给函数内部动态分配内存的值,这就是我传递了要动态分配内存的指针地址的原因。

正如我上面所演示的,没有理由传递指向函数指针的指针。 malloc分配的malloc是你永远使用的,你只需要跟踪它并在你不再需要它时调用freefree它。 如何跟踪内存并不重要 - 在这种情况下,只需返回一个指针就足够了。 修改func_1内部的pointer而不是捕获函数的返回值不会提供额外的好处,只会使代码变得比需要的更复杂。


我的印象是你对指针有些困惑,所以我建议你修改这个主题。 这里有一个关于指针的非常清楚的解释,其中也涵盖了指向指针的指针(以及指向指针的指针):指针如何在 C 中工作?


阅读更多:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM