C语言char**指针malloc/realloc内存分配异常问题求助
问题描述
我为测试char**类型的malloc与realloc操作,编写了简化代码:将字符串"debugging_in_progress"通过独立malloc的指针(非浅拷贝)存储到char**类型的texts数组中,初始数组大小为10,经两次扩容后变为40,需存储35个字符串。调试时发现以下问题:
- 程序输出丢失了前2个字符串的指针;
- 存储完所有指针后,使用
%s打印字符串会触发Segmentation Fault(段错误),即使避开疑似丢失的指针也无法解决; - 若将
texts初始分配大小设为4,程序会直接崩溃。
测试代码
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> void reallocMem(char **currArray, int* maxSize, int currSize); void memCheck(void ptr); int main() { char debug[100] = "debugging_in_progress"; int length = strlen(debug); char** texts = (char**) malloc (sizeof(char*) * 10); int max = 10; int c; for (int i= 0; i < 35; ++i) { reallocMem(texts,&max,i); texts[i] = (char*) malloc (sizeof(char) * length); printf("OG %d.: %p\n",i,texts[i]); for (int j = 0; j <= length; j++) { texts[i][j] = debug[j]; } printf("OG %d.TEXT: %s\n",i,texts[i]); c++; } for (int i = 10; i < 35; ++i) { printf("%d.:%p\n",i+1,texts[i]); // free(texts[i]); } printf("%d/%d",c,max); return 0; } void reallocMem(char **currArray, int* maxSize, int currSize) { if (currSize >= (*maxSize)) { (*maxSize) *= 2; currArray = (char*) realloc(currArray, (*maxSize) * sizeof(char*)); memCheck(currArray); } } void memCheck(void* ptr) { if (!ptr) { fprintf(stderr,"Row couldn't be processed: no memory left"); exit(7); } }
程序输出
▒'}@(}▒&}▒%}▒(})}<code>(} (}▒&}'} &}▒(}▒(} '}@&}&}</code>'} )}▒%}ugging_in_progress OG 3.: 00000208e97d23c0 OG 3.TEXT: debugging_in_progress OG 4.: 00000208e97d23e0 OG 4.TEXT: debugging_in_progress OG 5.: 00000208e97d2400 OG 5.TEXT: debugging_in_progress OG 6.: 00000208e97d2420 OG 6.TEXT: debugging_in_progress OG 7.: 00000208e97d2440 OG 7.TEXT: debugging_in_progress OG 8.: 00000208e97d2460 OG 8.TEXT: debugging_in_progress OG 9.: 00000208e97d2480 OG 9.TEXT: debugging_in_progress OG 10.: 00000208e97d12f0 OG 10.TEXT: debugging_in_progress OG 11.: 00000208e97d1310 OG 11.TEXT: debugging_in_progress OG 12.: 00000208e97d1330 OG 12.TEXT: debugging_in_progress OG 13.: 00000208e97d2550 OG 13.TEXT: debugging_in_progress OG 14.: 00000208e97d28a0 OG 14.TEXT: debugging_in_progress OG 15.: 00000208e97d2940 OG 15.TEXT: debugging_in_progress OG 16.: 00000208e97d27c0 OG 16.TEXT: debugging_in_progress OG 17.: 00000208e97d2840 OG 17.TEXT: debugging_in_progress OG 18.: 00000208e97d26c0 OG 18.TEXT: debugging_in_progress OG 19.: 00000208e97d25e0 OG 19.TEXT: debugging_in_progress OG 20.: 00000208e97d2880 OG 20.TEXT: debugging_in_progress OG 21.: 00000208e97d2900 OG 21.TEXT: debugging_in_progress OG 22.: 00000208e97d2860 OG 22.TEXT: debugging_in_progress OG 23.: 00000208e97d2820 OG 23.TEXT: debugging_in_progress OG 24.: 00000208e97d2680 OG 24.TEXT: debugging_in_progress OG 25.: 00000208e97d2700 OG 25.TEXT: debugging_in_progress OG 26.: 00000208e97d2620 OG 26.TEXT: debugging_in_progress OG 27.: 00000208e97d28c0 OG 27.TEXT: debugging_in_progress OG 28.: 00000208e97d28e0 OG 28.TEXT: debugging_in_progress OG 29.: 00000208e97d2720 OG 29.TEXT: debugging_in_progress OG 30.: 00000208e97d2640 OG 30.TEXT: debugging_in_progress OG 31.: 00000208e97d2600 OG 31.TEXT: debugging_in_progress OG 32.: 00000208e97d2760 OG 32.TEXT: debugging_in_progress OG 33.: 00000208e97d2920 OG 33.TEXT: debugging_in_progress OG 34.: 00000208e97d25c0 OG 34.TEXT: debugging_in_progress 11.:0000007373657267 12.:00000208e97d1310 13.:00000208e97d1330 14.:00000208e97d2550 15.:00000208e97d28a0 16.:00000208e97d2940 17.:00000208e97d27c0 18.:00000208e97d2840 19.:00000208e97d26c0 20.:00000208e97d25e0 21.:00000208e97d2880 22.:00000208e97d2900 23.:00000208e97d2860 24.:00000208e97d2820 25.:00000208e97d2680 26.:00000208e97d2700 27.:00000208e97d2620 28.:00000208e97d28c0 29.:00000208e97d28e0 30.:00000208e97d2720 31.:00000208e97d2640 32.:00000208e97d2600 33.:00000208e97d2760 34.:00000208e97d2920 35.:00000208e97d25c0 35/40
问题分析与修复
核心错误点
reallocMem参数传递错误:
函数接收的char **currArray是值传递,realloc后修改的是局部指针,主函数的texts指针不会更新。当realloc返回新地址时,主函数仍使用旧的失效指针,导致非法内存访问,这是崩溃和指针丢失的根本原因。- 字符串内存分配不足:
strlen(debug)返回不含终止符\0的长度,但malloc只分配了对应字符的空间,未给\0留位置。后续复制时j <= length会越界写入,破坏内存结构引发段错误。 - 未初始化变量
c:int c;未初始化就执行c++,属于未定义行为。 realloc类型转换错误:
强制转换为char*,但实际需要char**,类型不匹配导致指针操作错误。- 扩容时机错误:
判断条件currSize >= (*maxSize)会导致越界访问后才扩容,此时已触发非法内存操作。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> void reallocMem(char ***currArray, int* maxSize, int currSize); void memCheck(void* ptr); int main() { char debug[100] = "debugging_in_progress"; int length = strlen(debug); char** texts = (char**)malloc(sizeof(char*) * 10); int max = 10; int c = 0; // 初始化变量 for (int i = 0; i < 35; ++i) { reallocMem(&texts, &max, i); // 分配内存时多留一个字节存终止符 texts[i] = (char*)malloc(sizeof(char) * (length + 1)); memCheck(texts[i]); printf("OG %d.: %p\n", i, texts[i]); strcpy(texts[i], debug); // 替代手动复制,更简洁安全 printf("OG %d.TEXT: %s\n", i, texts[i]); c++; } for (int i = 0; i < 35; ++i) { printf("%d.:%p -> %s\n", i+1, texts[i], texts[i]); free(texts[i]); // 释放每个字符串的内存 } free(texts); // 释放指针数组的内存 printf("%d/%d\n", c, max); return 0; } void reallocMem(char ***currArray, int* maxSize, int currSize) { // 当前元素数量等于最大容量时扩容,避免越界 if (currSize == *maxSize) { *maxSize *= 2; // 正确转换为char**类型 *currArray = (char**)realloc(*currArray, *maxSize * sizeof(char*)); memCheck(*currArray); } } void memCheck(void* ptr) { if (!ptr) { fprintf(stderr, "Row couldn't be processed: no memory left"); exit(7); } }
修复说明
- 调整
reallocMem参数为char ***currArray,确保能修改主函数中texts指针的指向,扩容后使用新的有效地址。 - 字符串内存分配增加1个字节,保证能存储终止符
\0,避免越界写入。 - 初始化变量
c,消除未定义行为。 - 修正
realloc的类型转换,确保类型匹配。 - 调整扩容时机,在当前元素数量等于最大容量时就扩容,避免越界访问。
- 添加内存释放代码,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Ace_Orca
相关产品推荐
相关产品推荐

