使用malloc分配的内存不会在函数范围之外保留?

嗨,

我对C的malloc函数有点新,但据我所知,它应该将值存储在堆中,因此您可以使用来自原始范围之外的指针来引用它。 我创建了一个应该执行此操作的测试程序,但在运行程序后,我一直得到值0。 我究竟做错了什么?

int f1(int * b) { b = malloc(sizeof(int)); *b = 5; } int main() { int * a; f1(a); printf("%d\n", a); return 0; } 

是! a 按值传递,因此函数f1的指针b将是本地的..要么返回b

 int *f1() { int * b = malloc(sizeof(int)); *b = 5; return b; } int main() { int * a; a = f1(); printf("%d\n", *a); // keep it clean : free(a); return 0; } 

或传递a地址

 int f1(int ** b) { *b = malloc(sizeof(int)); **b = 5; } int main() { int * a; f1(&a); printf("%d\n", *a); // keep it clean : free(a); return 0; } 

看起来你误解了C的工作方式的一个基本部分 – 即它是一种“按值传递”的语言。 为了让main()知道你分配的内存,你必须把它取回来。 以下代码将为您提供所需的代码:

 int f1(int **b) { *b = malloc(sizeof(int)); **b = 5; } int main(int argc, char **argv) { int *a; f1(&a); printf("%d\n", *a); return 0; } 

这段代码与你的代码有一些区别; 首先, f1()的签名已经改变,因此它可以在传入的指针中返回malloc()调用的结果。 接下来,对f1()的调用已被更改为传递a而不是自身的地址 – 如果你希望它被f1() ‘填充’,则很重要,可以这么说。 最后, printf()中的printf()已更改为打印出指向的值而不是指针本身。

内存本身仍然存在,但它泄漏是因为你没有提供分配给调用者的指针。 此外,您打印时应该打印*a 。 最后,你没有从f1返回一个int。

尝试:

 void f1(int **b) { *b = malloc(sizeof(int)); **b = 5; } int main() { int *a; f1(&a); printf("%d\n", *a); free(a); return 0; } 

让我们假设您在调用函数f1之前为a赋值为NULL 。 现在定义f1的方式,它按值获取其参数(指向int指针)。 那就是b将是int *类型的另一个变量,它将是a的副本 。 所以b也会有NULL 。 现在在f1 ,通过为其分配使用malloc动态分配的内存地址,将值更改为b 。 可以说内存地址是0x123 。 作为此赋值的结果, b已将其值从NULL更改为0x123但是(在main )继续保持NULL ,因为更改b不会更改a ,因为它们是两个单独的变量。 因此,当您从函数f1返回时,a将保持不变。

有两种方法可以解决这个问题。 您可以使函数f1返回已更改的b的值,然后将其分配回main和2中,您可以传递a by地址,以便f1所做的任何更改也会影响in main

 // f1 now returns the value of b. int* f1() { int *b = malloc(sizeof(int)); *b = 5; return b; } int main() { int *a = NULL; a = f1(); // assign the return value of f1 to a. printf("%d\n", *a); // prints 5...not its *a not just a. return 0; } 

 // f1 now takes the address of a. void f1(int **b) { *b = malloc(sizeof(int)); // you are actually altering a indirectly. **b = 5; } int main() { int *a = NULL; f1(&a); // now pass the address of a to f1. printf("%d\n", *a); // prints 5...not its *a not just a. return 0; } 

函数返回时删除地址int *b 。 要保存它, 您需要使用指针指针

 int f1(int ** b) { *b = malloc(sizeof(int)); **b = 5; } 

您的问题实际上与malloc无关,而是您传递指针当前保存的值而不是它的地址。 请尝试以下方法:

 int f1(int ** b) { *b = malloc(sizeof(int)); **b = 5; } int main() { int * a; f1(&a); printf("%d\n", *a); return 0; } 

通过按原样传递指针值,创建的值malloc无法存储到指针中。