使用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无法存储到指针中。