循环第二次运行时出现Segmentation Fault(Core Dump)问题排查求助
问题原因分析与解决办法
先直接戳破核心问题:你的代码里指针操作完全搞错了,这就是第二次循环触发Segmentation Fault的根本原因,第一次没崩纯属运气好。
1. 致命的指针操作错误
你看这行代码:
**(str+i)=c;
str是char**类型(指向指针的指针),str+i表示把str这个指针往后移动i个char*的长度(也就是i * sizeof(char*)字节),然后**(str+i)相当于访问这个位置上的char*指向的第一个字符。但你要操作的是*str指向的字符数组的第i个元素啊!这完全不是一回事!
第一次运行时,str初始是NULL,第一次realloc后*str指向了分配的内存,但str+i可能刚好落在栈上的某个未被使用的区域,没触发内存访问错误;但第二次循环时,栈上的这个位置已经被其他数据覆盖,或者越界到了受保护的内存区域,直接就触发段错误了。
正确的写法应该是:
(*str)[i] = c;
或者等价的:
*(*str + i) = c;
这才是访问*str指向的字符数组的第i个元素。
2. 其他隐藏问题
除了上面的致命错误,还有两个容易踩的坑:
- 没有添加字符串终止符:你循环读取字符直到换行,但最后没有在字符串末尾加
'\0',后续任何使用这个字符串的操作(比如printf、strlen)都会因为找不到终止符而越界,迟早出问题。 getchar()返回值用char接收:getchar()的返回值是int类型,因为它要返回EOF(值为-1,是int类型),如果用char接收,当输入的字符是0xFF(比如某些扩展ASCII字符)时,会被错误地识别为EOF,而且在有符号char的环境下,会导致判断逻辑出错。
修正后的代码
#include <stdio.h> #include <stdlib.h> #define TOTAL_CHAR 100 // 假设你定义了这个宏,这里补一个示例值 char* get_command(char **str) { int c; // 用int接收getchar的返回值,兼容EOF判断 int i = 0, add = 0; printf("\tget command\n"); // 提前初始化内存,避免第一次循环的判断冗余 if (*str == NULL) { add = 1; *str = (char*)malloc(sizeof(char) * TOTAL_CHAR * add); if (*str == NULL) { fprintf(stderr,"ERROR:: malloc fail"); exit(EXIT_FAILURE); } printf("\tmemory allocate succeed\n"); } while ((c = getchar()) != '\n' && c != EOF) { if (i == TOTAL_CHAR * add) { add++; // 用临时变量存realloc结果,避免失败时丢失原指针 char* temp = (char*)realloc(*str, sizeof(char) * TOTAL_CHAR * add); if (temp == NULL) { fprintf(stderr,"ERROR:: realloc fail"); free(*str); // 避免内存泄漏 exit(EXIT_FAILURE); } *str = temp; printf("\tmemory reallocate succeed\n"); } (*str)[i] = (char)c; printf("\tchar should be: %c, actual: %c\n", (char)c, (*str)[i]); i++; } // 给字符串添加终止符,确保有足够空间 if (i == TOTAL_CHAR * add) { add++; char* temp = (char*)realloc(*str, sizeof(char) * TOTAL_CHAR * add); if (temp == NULL) { fprintf(stderr,"ERROR:: realloc fail for null terminator"); free(*str); exit(EXIT_FAILURE); } *str = temp; } (*str)[i] = '\0'; return *str; }
额外优化说明
- 用临时变量接收
realloc返回值:如果realloc失败返回NULL,直接赋值给*str会丢失原内存指针,导致内存泄漏。 - 提前初始化内存:第一次调用时
*str是NULL,提前分配内存避免了第一次循环的判断逻辑重复。 - 增加
EOF判断:处理用户输入结束(比如Ctrl+D)的边界情况。
内容的提问来源于stack exchange,提问作者Niv Turk
相关产品推荐
相关产品推荐

