在简单的C代码中分段错误(核心转储)

时间:2013-09-21 04:13:08

标签: c string segmentation-fault coredump

我是C的新人。我指的是Brian W Kernighian和Dennis Ritchie所着的“The C Programming Language”。 书中给出了一个指针增量和赋值的代码如下。

#include<stdio.h>

int main()
    {
        char *s = "Goal";
        char *t = "Home";
        while(*s++ = *t++) printf(*s);
        return 0;
    }

使用命令

保存和编译代码
gcc ptr.c -o ptr -std=c99

现在通过运行命令

运行代码
./ptr

我收到以下错误

  

分段错误(核心转储)

错误似乎在while循环条件内。 但代码与书中给出的完全相同。 我错过了什么?

3 个答案:

答案 0 :(得分:4)

st都是字符串文字,您无法修改字符串文字。但是这段代码

*s++ = *t++

将修改s,这会导致细分错误。

要解决此问题,请使用char数组。我还修改了printf部分以使其合法。

#include<stdio.h>

int main()
{
    char arr[] = "Goal";
    char *s = arr;
    char *t = "Home";
    while(*s++ = *t++) 
        ;
    printf("%s\n", arr);
    return 0;
}

但是,我认为这个程序最好使用单独的函数来复制字符串,程序会更清晰。

#include<stdio.h>
void my_strcpy(char *s, char *t);

int main()
{
    char s[] = "Goal";
    char *t = "Home";
    my_strcpy(s, t);
    printf("%s\n", s);
    return 0;
}

void my_strcpy(char *s, char *t)
{
    while(*s++ = *t++) 
        ;
}

答案 1 :(得分:1)

问题是printf期望第一个参数是char *,即指向字符或字符地址的东西。当你说printf(*s)时,你传递的是一个实际的字符,即0到255或-128到127之间的数字,程序会将该数字视为一个地址,这不会是您系统上的有效地址。

答案 2 :(得分:0)

当我们说* s =“hello”时,s指向文本段中存在的地址(“hello”进入文本段)。因此,显然更改文本段的值会导致SEGV终止。

对于s [] =“hello”如果我们执行* s ++,我们正在递增(修改)基址,因此我们得到“需要左值作为递增操作数”错误。