[英]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
是你永远使用的,你只需要跟踪它并在你不再需要它时调用free
来free
它。 如何跟踪内存并不重要 - 在这种情况下,只需返回一个指针就足够了。 修改func_1
内部的pointer
而不是捕获函数的返回值不会提供额外的好处,只会使代码变得比需要的更复杂。
我的印象是你对指针有些困惑,所以我建议你修改这个主题。 这里有一个关于指针的非常清楚的解释,其中也涵盖了指向指针的指针(以及指向指针的指针):指针如何在 C 中工作?
阅读更多:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.