LeetCode实现最长回文子串时出现heap buffer overflow的原因排查
问题分析与修复
你的代码触发heap-buffer-overflow的核心原因及修复方案如下:
1. 核心错误原因
- 返回字符串缺少终止符:C语言要求合法字符串必须以
'\0'结尾,但你用calloc(length, sizeof(char))分配的内存仅能容纳length个字符,未预留存储终止符的空间。复制子串后未添加'\0',判题程序读取返回值时会越界访问堆内存,触发溢出错误。 - 注释
if-else后错误消失的原因:此时l始终为0,length保持0,calloc(0, ...)返回NULL,判题程序处理空返回值时不会触发溢出。
另外,你的思路存在逻辑漏洞:最长公共子串不一定是回文(比如输入"abcxyzcba",反转后最长公共子串是"abc",但它不是回文),需要额外校验修正。
修复后的代码
char *longestPalindrome(char *s) { int len = strlen(s); if (len == 0) { return calloc(1, sizeof(char)); // 返回空字符串 } // 动态分配反转字符串数组,添加终止符避免未定义行为 char *c = malloc((len + 1) * sizeof(char)); for (int i = 0; i < len; i++) { c[i] = s[len - 1 - i]; } c[len] = '\0'; int st = 0; int length = 0; for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { int l = 0; for (int k = 0; ((i + k) < len) && ((j + k) < len); k++) { if (s[i + k] == c[j + k]) l++; else break; } // 校验公共子串是否为回文:原串结束位置对应反转串起始位置的原索引 if (l > length && (i + l - 1) == (len - 1 - (j + l - 1))) { length = l; st = i; } } } // 分配length+1个字符空间,预留终止符位置 char *ans = malloc((length + 1) * sizeof(char)); for (int i = 0; i < length; i++) { ans[i] = s[i + st]; } ans[length] = '\0'; // 添加字符串终止符 free(c); // 释放动态分配的内存 return ans; }
内容的提问来源于stack exchange,提问作者DhruvS
相关产品推荐
相关产品推荐

