AddressSanitizer: SEGV未知地址错误解析及单词反转代码排查
AddressSanitizer段错误解析与代码修复
错误含义解析
AddressSanitizer: SEGV on unknown address 0xffffffffffffffbe 是内存检测工具AddressSanitizer报出的段错误(Segmentation Fault):
- SEGV代表程序访问了操作系统不允许访问的内存区域;
- 地址
0xffffffffffffffbe是一个无效的64位内存地址(高位全1表示这是一个负数地址,属于用户空间不可访问的范围);- 报错根源是程序尝试读取非法内存,通常由未初始化变量、内存越界访问或指针操作逻辑错误导致。
代码问题分析与修复
你的代码目标是反转字符串中的每个单词,但存在多个致命逻辑错误,以下是逐一分析和修复方案:
1. 未初始化变量lastI导致非法内存访问
两个版本的代码中,lastI都没有初始赋值。如果遇到以下场景:
- 字符串最后一个字符不是空格,内层
while循环不会执行,lastI保留随机脏值; - 字符串开头就是空格,
firstI设为0,但lastI未被赋值;
后续交换循环使用未初始化的lastI,会直接访问超出数组范围的非法内存,触发段错误。
2. 单词边界判断逻辑完全错误
你当前的while循环是++i < n && res[i] == ' ',这个逻辑是跳过空格,但没有正确定位单词的末尾。正确逻辑应该是找到单词的最后一个非空格字符,即先跳过空格定位单词开头,再遍历到单词结尾。
3. 反转循环条件写反
第二个while循环的条件是firstI > lastI,这完全不符合反转逻辑——只有当firstI < lastI时,才需要交换两端字符,否则循环根本不会执行,无法实现单词反转。
4. 初始代码的额外问题
- 初始代码中
malloc(sizeof(char)*n)未给字符串末尾的'\0'预留空间,会导致字符串操作越界; - 错误使用
strcmp(res[i], ' '):strcmp用于比较字符串,单个字符比较应直接用==。
修复后的完整代码
char * reverseWords(char * s){ int n = strlen(s); // 分配n+1个字符空间,预留'\0'的位置 char *res = malloc(n + 1); if (res == NULL) { // 增加malloc失败的判断,避免空指针 return NULL; } strcpy(res, s); int firstI, lastI; for (int i = 0; i < n; i++){ // 跳过开头的空格,定位单词的起始位置 while (i < n && res[i] == ' ') { i++; } if (i >= n) { // 已经到字符串末尾,退出循环 break; } firstI = i; // 找到单词的末尾(下一个空格或字符串结束) while (i < n && res[i] != ' ') { i++; } lastI = i - 1; // 反转当前单词:firstI < lastI时交换字符 while (firstI < lastI){ char temp = res[firstI]; res[firstI++] = res[lastI]; res[lastI--] = temp; } } // 确保字符串以'\0'结尾 res[n] = '\0'; return res; }
修复要点总结
- 给
lastI正确赋值,确保每次反转循环使用的是有效的单词末尾索引; - 修正单词边界判断逻辑,正确定位每个单词的起始和结束位置;
- 反转循环条件改为
firstI < lastI,保证反转逻辑正常执行; - 分配内存时预留
'\0'的空间,增加malloc失败的安全判断; - 单个字符比较用
==而非strcmp。
内容的提问来源于stack exchange,提问作者user20977916
相关产品推荐
相关产品推荐

