A函数里调用B函数 ,且往B函数里传了个二级指针,并在B返回后,释放该指针
A函数里调用B函数 ,且往B函数里传了个二级指针,并在B返回后,释放该指针
下面是一个完整的代码示例,演示了函数A调用函数B并传入二级指针,函数B内部分配内存,函数A在B返回后使用并释放该指针。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 函数B:负责分配内存并初始化数据
// 参数 pp 是一个二级指针,它接收的是函数A中一级指针的地址
void functionB(char** pp) {
// 通过解引用二级指针pp,我们实际操作的是函数A中的那个一级指针
// 为其在堆上分配100字节的内存
*pp = (char*)malloc(100 * sizeof(char));
// 良好的编程习惯:检查内存是否分配成功
if (*pp == NULL) {
fprintf(stderr, "Memory allocation failed in functionB.\n");
return; // 分配失败直接返回
}
// 向分配的内存中写入数据,这里拷贝一个字符串
strcpy(*pp, "Hello, this data is allocated in functionB.");
printf("Inside functionB: Memory allocated and data written.\n");
}
// 函数A
void functionA() {
char* p = NULL; // 在函数A中声明一个一级指针,并初始化为NULL
printf("Inside functionA, before calling functionB:\n");
printf("Address stored in p: %p\n", (void*)p); // 此时p应为NULL (0x0)
// 调用函数B,并传入指针p的地址(即二级指针&p)
functionB(&p);
printf("\nInside functionA, after calling functionB:\n");
if (p != NULL) {
printf("Address stored in p: %p\n", (void*)p); // 此时p应指向functionB分配的内存
printf("Data pointed by p: %s\n", p); // 打印p指向的数据
// 使用完毕后,释放functionB分配的内存
free(p);
p = NULL; // 将p置为NULL,避免成为野指针
printf("Memory has been freed in functionA.\n");
} else {
printf("Memory allocation in functionB failed, p is still NULL.\n");
}
}
int main() {
functionA();
return 0;
}
关键点解释
为什么用二级指针:在 functionA 中,我们声明了一级指针 p 。为了能让 functionB 改变 p 本身的值(从NULL改为一个有效的内存地址),我们需要将 p 的地址( &p ,类型为 char** )传给 functionB 。这样, functionB 内部的 *pp = malloc(...) 操作实际上是在修改 functionA 中的 p 变量。
内存分配与释放:内存是在 functionB 中通过 malloc 分配的,但释放的责任在调用方 functionA 。这是一种常见的模式——分配内存的函数和释放内存的函数应该是同一层级,或者由调用者负责释放,这样可以更好地管理内存生命周期,避免内存泄漏。
错误检查:在 functionB 分配内存后和 functionA 使用指针前,都检查了指针是否为 NULL ,这是防止程序崩溃的好习惯。
避免野指针:在 functionA 中释放内存后,立即将 p 置为 NULL ,这样可以防止后续误用已经释放的内存。
预期输出示例
(具体内存地址每次运行可能不同)
Inside functionA, before calling functionB:
Address stored in p: (nil)
Inside functionB: Memory allocated and data written.Inside functionA, after calling functionB:
Address stored in p: 0x55a1a2b3c4d0
Data pointed by p: Hello, this data is allocated in functionB.
Memory has been freed in functionA.
这个示例清晰地展示了如何使用二级指针在函数间传递动态分配的内存,并确保内存被正确释放。