C语言被调函数中使用realloc逐元素分配二维数组内存触发段错误
代码崩溃的核心原因
你的代码存在3个直接触发段错误的致命问题:
main函数中定义的char **a是未初始化的野指针,没有先给它分配存储char*类型元素的数组内存,就直接执行a[0] = malloc(5),这一步本身就已经触发未定义内存访问,部分编译环境下可能刚好随机值落在可写内存区间,才会撑到后续realloc行才崩溃。substr函数内的realloc调用参数完全错误:你传入的形参a是char***类型,指向的是main函数中栈上的二级指针变量a,根本不是之前malloc/realloc返回的合法堆内存地址,realloc收到非法地址作为第一个参数必然触发段错误;同时赋值目标也不匹配,*(a +k)的类型是char*,和realloc返回的void*虽然语法上可以强转,但逻辑上你是想给数组第k个元素分配字符串空间,操作层级完全错了。- 头文件引用不规范:
<malloc.h>是非标准的老旧头文件,标准C环境下内存分配函数的声明在<stdlib.h>中,错误引用头文件会导致函数隐式声明,引发未定义行为。
修正后的可运行代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int substr(char *arr, char c, char ***a, int k) { // 第一次解引用*a拿到main中的二级指针(即char*数组的基地址) // 给数组第k个元素分配5字节的字符串存储空间 (*a)[k] = realloc((*a)[k], 5); if ((*a)[k] == NULL) { return -1; // 内存分配失败返回错误码 } // 此处可补充你的字符串分割、拷贝逻辑 return 0; } int main() { char *arr = "this is a new string. check it out"; char **a; // 先给二级指针分配内存:存储2个char*元素,对应索引0、1 a = malloc(sizeof(char*) * 2); if (a == NULL) { return 1; } a[0] = malloc(5); if (a[0] == NULL) { free(a); return 1; } // 其他业务逻辑 int count = substr(arr, ' ', &a, 1); // 使用完成后逐层释放内存,避免泄漏 free(a[0]); free(a[1]); free(a); return 0; }
编写多级指针内存操作的注意事项
- 每一层解引用要对应正确的类型:三级指针
char***第一次解引用拿到二级指针char**(即一级指针数组的基地址),第二次解引用才能拿到存储字符串的一级指针char*,不要跳级操作。 - 所有
malloc/realloc的返回值必须做判空处理,内存分配失败时会返回NULL,直接解引用会触发崩溃。 - 野指针禁止直接解引用:所有指针在第一次解引用前,必须让它指向合法的、已分配的内存地址(栈变量地址或者堆分配地址)。
realloc的第一个参数必须满足两个条件之一:要么是NULL,要么是之前内存分配函数返回的、尚未被free的合法堆地址,传入栈地址、已释放的堆地址都会触发内存错误。
内容的提问来源于stack exchange,提问作者user786
相关产品推荐
相关产品推荐

