C语言结构体数组双指针内存分配异常:r及r[0]变为0x0的问题
问题分析与解决方案
嘿,我来帮你捋捋这个问题~你的代码核心bug出在对双指针形参的理解偏差:当你在func函数里直接给r赋值malloc的结果时,你修改的只是函数内部的局部变量副本,外部传入的实参根本不会同步这个变化。所以函数退出后,外部的r还是原来的初始值(大概率是0x0),而你在函数里分配的内存还会变成没人管的“孤儿”,造成内存泄漏。
修正后的完整代码示例
先给你改好的可运行代码,再一步步解释关键逻辑:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> struct R { int x; int y; char * z; }; void func(struct R **r) { // 1. 给外部的指针数组分配内存:*r指向外部传入的struct R**变量 *r = malloc(4 * sizeof(struct R *)); if (*r == NULL) { perror("Failed to allocate pointer array"); return; } // 2. 给数组第一个元素分配结构体内存 (*r)[0] = malloc(sizeof(struct R)); if ((*r)[0] == NULL) { perror("Failed to allocate struct R"); free(*r); // 先释放已分配的数组,避免内存泄漏 *r = NULL; return; } // 3. 给结构体成员赋值 (*r)[0]->x = 1; (*r)[0]->y = 2; // 用strdup分配字符串内存(内部已完成malloc+strcpy),也可以手动malloc+strcpy (*r)[0]->z = strdup("Hello World"); if ((*r)[0]->z == NULL) { perror("Failed to allocate string"); free((*r)[0]); free(*r); *r = NULL; return; } } int main() { struct R **my_r = NULL; func(&my_r); // 验证结果 if (my_r != NULL && my_r[0] != NULL) { printf("x: %d, y: %d, z: %s\n", my_r[0]->x, my_r[0]->y, my_r[0]->z); // 4. 逆向释放内存,避免泄漏 free(my_r[0]->z); free(my_r[0]); free(my_r); my_r = NULL; } return 0; }
关键修正点说明
- 操作
*r而非r:r是函数的形参,它指向外部的struct R**变量,只有修改*r(也就是外部真正的指针数组变量),才能让外部获取到分配的内存地址。 - 必须检查
malloc返回值:任何动态内存分配都可能失败并返回NULL,不检查的话会导致空指针访问崩溃。 - 内存释放要顺序正确:先释放结构体内部的字符串,再释放结构体本身,最后释放指针数组,顺序反了会触发野指针问题。
内容的提问来源于stack exchange,提问作者Bhawan
相关产品推荐
相关产品推荐

