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

malloc()无法在C中的函数内分配内存,c,pointers,C,Pointers,我想在函数中动态分配内存。函数名为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++) {

我想在函数中动态分配内存。函数名为
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
   }    
}

当我试着运行这个程序时,我得到了一个分段错误(SIGSEGV)。我使用GDB来定位这个错误的来源,结果发现for循环中的线路是这个错误的罪魁祸首

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

我想知道:

  • 为什么我会犯这个错误

  • 如何解决这个问题

谢谢你的帮助

[]
(数组订阅)运算符的优先级为2

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

在您的代码中,
*目的地[i]
的意思与
*(目的地[i])
相同。此值未初始化,导致分段错误

如果您使用操作的显式优先级
(*目的地)[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
   }    
}
void func_1(int**destination)
{
*目的地=(int*)马洛克(sizeof(int)*10);
对于(int i=0;i<10;i++)
{
(*目的地)[i]=i;//无分段错误
}    
}
您可以阅读更多关于优先级的信息

完整代码:

#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(整数**目的地)
{
*目的地=(int*)马洛克(sizeof(int)*10);
对于(int i=0;i<10;i++)
{
(*目的地)[i]=i;
}
}
int main()
{
int*指针;
func_1(&指针);
返回0;
}
为什么我会犯这个错误

您正在覆盖
目标
指针,而不是将
malloc
返回的值赋给
目标
指针指向的指针

  • 您应该键入
    **destination=malloc(sizeof(int)*10)而不是
    *destination=(int*)malloc(sizeof(int)*10)
  • 您应该键入
    (**目的地)[i]=i
    ,而不是
    *目的地[i]=i

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

在您的情况下,这意味着您需要键入
(**目的地)[i]=i
而不是
**destination[i]=i
,因为否则
[i]
将在
**
之前计算
[i]
,并最终间接指向a(这通常会导致分段错误,在这种情况下是绝对肯定的,因为当
i==0
时,您引用的是空指针)


如何解决这个问题

“只要让它工作”修复就是我上面介绍的修复

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

以下内容正是您想要的,没有任何不必要的复杂性:

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

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

正如我在上面演示的,没有理由传递指向函数指针的指针。使用
malloc
分配的内存是您可以永远使用的,您只需跟踪它,并在不再需要时通过调用
free
释放它。如何跟踪内存并不重要——在这种情况下,只需返回一个指针就足够了。在
func_1
中修改
指针
,而不是捕获函数的返回值,不会带来额外的好处,只会使代码变得更加复杂


我的印象是你对指针有些困惑,所以我建议你修改这个主题。这里有一个关于指针的非常清楚的解释,它还包括指向指针的指针(以及指向指向指针的指针):


阅读更多:


应用此解决方案确实消除了分段错误。您忘记了释放堆对象。
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;
}