函数调用中的Malloc似乎在返回时被释放?
时间:2020-03-06 14:27:45 来源:igfitidea点击:
我认为我已经将其归结为最基本的情况:
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 car[3]=-1869558540 a.out(4100) malloc: *** error for object 0x8fe01037: Non-aligned pointer being freed *** set a breakpoint in malloc_error_break to debug >
如果有人能阐明我的理解失败的地方,将不胜感激。
解决方案
我们已经在foo中分配了arr,但是指针值存储在调用堆栈中。如果要执行此操作,请按照以下步骤操作:
void foo( int ** arr) { *arr = (int *)malloc( sizeof(int) * 25 ); (*arr)[3] = 69; }
并且在主要方面,只需传递一个指向foo的指针(如foo(&arr))
我们通过值而不是通过引用传递指针,因此无论我们在foo内部对arr进行什么操作,都不会在foo函数之外产生任何影响。
正如m_pGladiator所写的那样,一种方法是这样声明对指针的引用(仅在C ++ btw中可能。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; }
另一种(更好的恕我直言)方式是不将指针作为参数传递而返回指针:
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 ++中,修改foo以接受对指针的引用更为简单。我们需要在C ++中进行的唯一更改是将foo更改为
void foo(int * & arr)
由于我们要按值传递指针,因此main内部的arr指针不会指向已分配的内存。这意味着两件事:我们遇到了内存泄漏(不,在foo函数完成后不会释放内存),并且当我们访问main内部的arr指针时,我们正在访问任意范围的内存,因此我们不会不会打印出3个,因此free()拒绝工作。我们很幸运,在main内部访问arr [3]时没有遇到分段错误。