You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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调试:

  1. 编译时添加调试符号:gcc -g your_code.c -o your_program
  2. 启动gdb:gdb ./your_program
  3. 运行程序:run
  4. 触发段错误后,执行backtrace查看调用栈,直接定位出错代码行

内容的提问来源于stack exchange,提问作者stefanoukios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:52:39