Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数调用中的Malloc似乎在返回时被释放?_C_Pointers_Malloc - Fatal编程技术网

函数调用中的Malloc似乎在返回时被释放?

函数调用中的Malloc似乎在返回时被释放?,c,pointers,malloc,C,Pointers,Malloc,我想我已经把它归结为最基本的情况: int main(int argc, char ** argv) { int * arr; foo(arr); printf("car[3]=%d\n",arr[3]); free (arr); return 1; } void foo(int * arr) { arr = (int*) malloc( sizeof(int)*25 ); arr[3] = 69; } 输出如下: ./a.out 汽车[3]=-18695585

我想我已经把它归结为最基本的情况:

int main(int argc, char ** argv) {
  int * arr;

  foo(arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int * arr) {
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
}
输出如下:

./a.out
汽车[3]=-1869558540
a、 out(4100)malloc:**对象0x8fe01037的错误:未对齐指针
被释放
***在malloc\u error\u break中设置断点以进行调试
>

如果有人能说明我的理解在哪里失败,我们将不胜感激。

您已经在foo中分配了arr,但指针值存储在调用堆栈中。如果要执行此操作,请按如下方式执行:

void foo( int ** arr) {
    *arr = (int *)malloc( sizeof(int) * 25 );
    (*arr)[3] = 69;
}

大体上,只需将指针传递给foo(比如foo(&arr))

您通过值传递指针,而不是通过引用传递指针,因此在foo内部使用arr所做的任何操作都不会在foo函数外部产生影响。 正如M.PgDadioter所写的那样,一种方法是声明对这样的指针的引用(只有C++中的BTW.C不知道引用):

另一种(更好的imho)方法是不将指针作为参数传递,而是返回指针:

int main(int argc, char ** argv) {
  int * arr;

  arr = foo();
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

int * foo(void ) {
  int * arr;
  arr = (int*) malloc( sizeof(int)*25 );
  arr[3] = 69;
  return arr;
}
您可以将一个指针传递给一个指针。这是通过引用传递的C方式。使语法有点复杂,但很好-这就是C的用法

int main(int argc, char ** argv) {
  int * arr;

  foo(&arr);
  printf("car[3]=%d\n",arr[3]);
  free (arr);
  return 1;
}

void foo(int ** arr ) {
  (*arr) = (int*) malloc( sizeof(int)*25 );
  (*arr)[3] = 69;
}

如果未通过引用(&)传入参数(arr),则无法更改该参数的值。通常,您希望返回指针,因此您的方法应为:

arr=foo()


试图重新分配论点是不好的;我不推荐(&)解决方案。

foo接收int指针的本地副本,将内存分配给它,并在它超出范围时泄漏该内存

解决此问题的一种方法是让foo返回指针:

int * foo() {
  return (int*) malloc( sizeof(int)*25 );
}

int main() {
    int* arr = foo();
}
另一种方法是向foo传递指向指针的指针

void foo(int ** arr) {
   *arr = malloc(...);
}

int main() {
    foo(&arr);
}
在C++中,修改FO以接受对指针的引用更为简单。C++中唯一需要的改变是将FoO更改为

void foo(int * & arr)

因为您是按值传递指针,所以main中的arr指针没有指向分配的内存。这意味着两件事:内存泄漏(不,函数foo完成后内存不会释放),当访问main中的arr指针时,访问的是任意范围的内存,因此无法打印出3,因此free()拒绝工作。您很幸运,在访问main中的arr[3]时没有出现分段错误。

我可以说,请不要强制转换malloc的返回值吗?它不是必需的,可以隐藏错误。@freespace,这是我多年来养成的习惯。每个人和我都必须通过静态代码分析工具发送我的代码,他们抱怨没有使用指针。很抱歉让您挂起而没有回复:除非我对所有评论进行投票,否则在评论中没有找到回复的好方法:)我在@freespace中留下了答案,我知道-希望有一天会添加一个通过注释通知的功能。前两个是使用函数分配内存的最快方法?
void foo(int * & arr)