我想在函数内部动态分配内存。该函数名为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循环内的行是导致此错误的元凶。
请注意,一旦函数退出,我希望保留分配给函数内部动态分配内存的值,这就是我将要分配的指针地址传递给它的原因动态存储。
我想知道:
为什么会出现此错误?
如何解决?
感谢帮助!
答案 0 :(得分:1)
[]
(数组下标)运算符的优先级为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
}
}
您可以了解有关优先级here
的更多信息完整代码:
#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;
}
答案 1 :(得分:0)
为什么会出现此错误?
您将覆盖destination
指针,而不是将malloc
返回的值赋给destination
指针指向的指针。
*destination = (int*)malloc(sizeof(int) * 10)
而不是**destination = malloc(sizeof(int) * 10)
。*destination[i] = i
而不是(**destination)[i] = i
。在C中,数组下标运算符[]
的优先级高于间接运算符*
的优先级。除此之外,前者是从左到右的关联,而后者是从右到左的关联。
在您的情况下,这意味着您需要输入(**destination)[i] = i;
而不是**destination[i] = i
,因为否则[i]
将在**
之前被求值,并且最终将a wild pointer(这在一般情况下极有可能导致分段错误,在这种情况下绝对可以肯定,因为在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
分配的内存是您永远可以使用的内存,您只需要跟踪它并在不再需要它时通过调用free
来释放它。跟踪内存的方式无关紧要-在这种情况下,仅返回一个指针就足够了。在pointer
内修改func_1
而不是捕获函数的返回值不会带来任何额外的好处,只会使代码变得比所需复杂。
我觉得您对指针有些困惑,因此建议您修改主题。这是关于指针的非常清楚的说明,其中还包括指向指针的指针(以及指向指针的指针):How do pointers work in C?
了解更多: