自定义mystrcat函数出现段错误(exit code 139)如何解决?
自定义strcat函数触发段错误(Exit Code 139)的排查与修复
Exit Code 139对应SIGSEGV信号,本质是非法内存访问。针对你编写mystrcat时遇到的问题,核心原因大概率集中在内存分配错误、只读内存误用或函数逻辑漏洞上,以下是具体排查和修复方案:
常见问题与修复
1. 内存分配大小计算错误
如果用malloc分配目标内存,必须计算**第一个字符串长度 + 第二个字符串长度 + 1(用于终止符\0)**的总大小,否则会因越界写内存触发段错误。
错误示例
// 仅分配了第一个字符串的长度,空间不足 char* str3 = malloc(strlen(str1)); mystrcat(str3, str1); mystrcat(str3, str2); // 越界写内存,触发SIGSEGV
正确写法
size_t len1 = strlen(str1); size_t len2 = strlen(str2); // 分配总长度+1的内存,确保容纳两个字符串和终止符 char* str3 = malloc(len1 + len2 + 1); if (str3 == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } // 先将第一个字符串拷贝到目标内存 strcpy(str3, str1); // 再拼接第二个字符串 mystrcat(str3, str2);
2. 误写只读内存
如果将字符串字面量直接赋值给char*(如char* dest = "hello";),该指针指向只读数据段,修改它会触发段错误。必须确保目标字符串指向可写内存(栈数组或malloc分配的堆内存)。
错误示例
// "hello"是只读字面量,无法修改 char* dest = "hello"; mystrcat(dest, "world"); // 写入只读内存,触发段错误
正确写法
// 方案1:使用栈数组(确保大小足够) char dest[100] = "hello"; mystrcat(dest, "world"); // 方案2:使用堆内存 char* dest = malloc(strlen("hello") + strlen("world") + 1); strcpy(dest, "hello"); mystrcat(dest, "world");
3. 自定义mystrcat的逻辑漏洞
标准strcat要求目标字符串有足够可写空间,源字符串为只读。你的实现需保证:
- 先遍历到目标字符串的终止符
\0 - 逐个拷贝源字符串字符,直到源字符串的终止符
- 最后添加终止符
\0
正确的mystrcat实现
#include <stdio.h> #include <stdlib.h> #include <string.h> char* mystrcat(char* dest, const char* src) { char* start = dest; // 保存目标起始地址用于返回 // 移动到目标字符串末尾 while (*dest != '\0') { dest++; } // 拷贝源字符串到目标末尾 while (*src != '\0') { *dest = *src; dest++; src++; } *dest = '\0'; // 添加终止符 return start; } int main() { char str1[100], str2[100]; // 用fgets读取字符串,避免scanf截断空格,同时去除换行符 fgets(str1, sizeof(str1), stdin); str1[strcspn(str1, "\n")] = '\0'; fgets(str2, sizeof(str2), stdin); str2[strcspn(str2, "\n")] = '\0'; size_t total_len = strlen(str1) + strlen(str2) + 1; char* str3 = malloc(total_len); if (str3 == NULL) { perror("malloc failed"); return 1; } strcpy(str3, str1); mystrcat(str3, str2); printf("拼接结果:%s\n", str3); free(str3); // 释放堆内存,避免泄漏 return 0; }
4. 调试定位技巧
如果仍无法定位问题,可使用gdb调试:
- 编译时添加调试符号:
gcc -g your_code.c -o your_program - 启动gdb:
gdb ./your_program - 运行程序:
run - 触发段错误后,执行
backtrace查看调用栈,直接定位出错代码行
内容的提问来源于stack exchange,提问作者stefanoukios
相关产品推荐
相关产品推荐

