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

为何ret已获取内存地址,执行strcpy仍触发Segmentation fault?

段错误原因分析及修复

为啥会触发段错误?

  • 你代码里的"This string literal is arbitrary"是字符串字面量,程序运行时会把它放到只读内存区域(比如rodata段),这块内存只能读,绝对不能写。
  • strstr(tmp, "literal")返回的ret指针,指向的就是这个只读区域里"literal"的起始位置。你调用strcpy(ret, "")想往这块只读内存里写东西,直接违反了内存访问规则,系统就抛出段错误了。
  • 还有个逻辑顺序问题:你先执行strcpy再判断ret是否为空,如果strstr没找到子串,ret是NULL,这时候strcpy直接就崩了。

怎么改?

要修改字符串内容,得先把字符串放到可写的内存里,比如栈上的数组或者堆内存:

方法1:用栈上的数组(简单直接)

#include <stdio.h>
#include <string.h>

int main() {
    // 把字符串字面量复制到栈上的数组,数组是可写的
    char tmp[] = "This string literal is arbitrary";
    char *ret = strstr(tmp, "literal");

    if (ret) {
        // 直接把第一个字符改成'\0'就清空后面内容了,比strcpy高效
        *ret = '\0';
        printf("找到子串,地址:%p\n", ret);
        printf("修改后的字符串:%s\n", tmp);
    } else {
        printf("没找到子串\n");
    }
    
    return 0;
}

方法2:用堆内存(适合字符串长度不确定的情况)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    const char *src = "This string literal is arbitrary";
    // 分配足够内存,复制原字符串到堆上
    char *tmp = malloc(strlen(src) + 1);
    if (!tmp) {
        perror("内存分配失败");
        return 1;
    }
    strcpy(tmp, src);

    char *ret = strstr(tmp, "literal");
    if (ret) {
        strcpy(ret, "");
        printf("找到子串,地址:%p\n", ret);
        printf("修改后的字符串:%s\n", tmp);
    } else {
        printf("没找到子串\n");
    }

    free(tmp); // 用完堆内存记得释放
    return 0;
}

额外提醒

  • 字符串字面量就算用char*指向它,也不能修改内容,这是C语言里的未定义行为,大部分系统都会直接崩溃。
  • 调用strstr这类可能返回NULL的函数,一定要先判断返回值不为空,再做后续操作,避免空指针访问崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 03:30:56