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

为何我的C语言基础代码触发Segmentation Fault(段错误)?

解决squeeze函数的段错误问题

问题描述

要实现squeeze(char s1[], char s2[])函数,功能是删除s1中所有出现在s2里的字符并打印结果。但运行代码时,在s1[j] = s1[i];行触发Segmentation Fault,拆分代码后确认段错误出现在s1[j]行。排查后认为未访问越界数组索引,用gdb也能读取s1[j]和s1[i],刚学C不知道问题所在。

原代码

#include <stdio.h>
void squeeze(char s1[], char s2[]);

int main()
{
    squeeze("test string", "ts");
    
    return 0;
}

void squeeze(char s1[], char s2[])
{
    int i, j, k;

    for (k = 0; s2[k] != '\0'; k++) {
        for (i=j=0; s1[i] != '\0'; i++)
            if (s1[i] != s2[k]) {
                s1[j] = s1[i];
                ++j;
            }
        s1[j] = '\0';
    }
    printf("%s", s1);
}

GDB报错信息

Program received signal SIGSEGV, Segmentation fault.
squeeze (s1=0x555555556007 "test string", s2=0x555555556004 "ts") at main.c:18
18                  s1[j] = s1[i];

问题原因

核心问题是字符串字面量是只读的:
你在main函数中传入的"test string"是字符串字面量,它被存储在程序的只读数据段中。C语言中,字符串字面量本质是const char*类型,即使编译器允许用char[]接收,也不允许修改其内容。当你的代码尝试通过s1[j] = s1[i];修改这块只读内存时,操作系统会触发段错误(SIGSEGV)来阻止非法写操作。

解决方案

将传入的字符串字面量改为可修改的字符数组,让s1指向栈上的可写内存区域:

修改后的代码

#include <stdio.h>
void squeeze(char s1[], char s2[]);

int main()
{
    char s1[] = "test string"; // 定义为可修改的字符数组,复制字符串字面量到栈上
    squeeze(s1, "ts");
    
    return 0;
}

void squeeze(char s1[], char s2[])
{
    int i, j, k;

    for (k = 0; s2[k] != '\0'; k++) {
        for (i=j=0; s1[i] != '\0'; i++)
            if (s1[i] != s2[k]) {
                s1[j] = s1[i];
                ++j;
            }
        s1[j] = '\0';
    }
    printf("%s", s1);
}

解释

定义char s1[] = "test string";时,编译器会在栈上分配足够的内存,把字符串字面量"test string"的内容复制到这个数组中。此时s1指向的是栈上的可写内存,后续修改s1的操作就不会触发段错误了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:24:08