C语言自定义_strdup函数运行触发SIGSEV段错误求助
自定义_strdup函数SIGSEGV段错误排查
你的代码一共有5处明确的错误,任意一处都可能触发段错误或逻辑异常:
- 字符串终止符判断错误:C语言字符串的结束标记是转义字符
'\0'(ASCII值为0),你写的判断条件str[size] != '0'是在匹配数字字符'0'(ASCII值为48),会导致第一个for循环持续越界访问str指向的内存区域,直到读到内存中随机出现的数字0字符才停止,越界读本身就可能触发段错误,算出的长度size也是完全错误的随机值。 - 循环体缺失大括号:第一个for循环没有用大括号包裹要执行的逻辑,C语言中无大括号的循环仅会把紧接的第一行代码作为循环体,也就是说
mp = malloc(size * sizeof(str) + 1);会在for循环的每一次迭代中都执行一次,不仅会造成严重的内存泄漏(之前申请的内存没有指针持有、无法释放),最终mp指向的内存大小也是基于错误的size值申请的,完全不符合预期。 - malloc内存大小计算错误:
sizeof(str)计算的是char*指针本身的长度(64位系统为8字节、32位系统为4字节),不是char类型的长度,这里完全不需要乘指针长度,正确的空间大小应该是长度+1(+1是为了存字符串结束符'\0')。 - 循环计数器未初始化:第二个拷贝循环用的变量
i是栈上的局部变量,没有手动赋初始值0,初始值是栈内存残留的随机垃圾值,会导致循环起始索引完全不可控,要么不执行拷贝,要么越界读写内存触发段错误。 - 拷贝完成后未追加字符串结束符:就算前面的拷贝逻辑正常执行,你没有在拷贝完成后的
mp[size]位置写入'\0',返回的字符串没有合法终止标记,后续对该字符串做操作时会持续越界读内存,同样会触发段错误。
修正后的可正常运行代码
char *_strdup(char *str) { int i = 0, size = 0; char *mp; if (str == NULL) { return NULL; } // 正确计算字符串长度,匹配'\0'结束符 while (str[size] != '\0') { size++; } // 循环结束后统一申请内存,空间为长度+1存结束符 mp = malloc(size + 1); if (mp == NULL) { return NULL; } // 从i=0开始逐字节拷贝 for (i = 0; i < size; i++) { mp[i] = str[i]; } // 末尾追加字符串结束符 mp[size] = '\0'; return mp; }
额外注意:实际使用时malloc申请到的内存使用完需要手动调用
free()释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者pythonnewbie
相关产品推荐
相关产品推荐

