自定义strstr实现出现内存访问错误的排查与优化咨询
内存访问错误的原因分析
- 返回值类型完全不匹配:函数声明返回
char*,但匹配成功时却返回size_t类型的i。把整数偏移量直接当成指针地址返回,必然指向非法内存区域,触发访问错误。 - 空
needle处理逻辑错误:当needle是空字符串时,length为0,内层循环直接跳过,随后判断j == length成立,返回i(此时i为0),同样因类型不匹配导致非法内存访问。 - 指针越界风险:在内层匹配循环中,
p1会持续递增,即使haystack剩余字符长度小于needle长度,仍会继续访问*p1,可能越过haystack的末尾\0访问非法内存。
修复并优化后的代码
#include <assert.h> #include <stddef.h> char *mystrstr(const char *haystack, const char *needle) { const char *p1; const char *p2; size_t needle_len = 0; assert(haystack != NULL && needle != NULL); // 计算needle的长度 while (needle[needle_len] != '\0') { needle_len++; } // 处理边界:needle为空时,按标准strstr返回haystack指针 if (needle_len == 0) { return (char *)haystack; } p1 = haystack; // 仅当haystack剩余长度足够容纳needle时,才继续匹配 while (*(p1 + needle_len - 1) != '\0') { p2 = needle; size_t j = 0; // 逐字符匹配 while (j < needle_len && *p1 == *p2) { p1++; p2++; j++; } if (j == needle_len) { // 返回匹配起始位置的指针 return (char *)(p1 - needle_len); } // 回溯到下一个起始位置 p1 = p1 - j + 1; } return NULL; }
优化说明
- 修正返回值问题:匹配成功时通过指针回溯计算起始地址,返回合法的
char*类型指针,而非整数偏移量。 - 完善边界处理:明确处理
needle为空的情况,符合标准strstr的行为规范。 - 避免无效循环:外层循环添加长度校验,确保
haystack剩余字符足够容纳needle,减少无效匹配并避免指针越界。 - 简化逻辑结构:移除冗余的
i变量,直接通过指针操作实现匹配与回溯,代码更简洁直观。
内容的提问来源于stack exchange,提问作者Rose Ben Ann
相关产品推荐
相关产品推荐

