写入c-string

时间:2009-09-10 14:26:26

标签: c segmentation-fault cstring c-strings kr-c

我的代码段错误,我不知道为什么。

 1  #include <stdio.h>
 2
 3  void overwrite(char str[], char x) {
 4    int i;
 5    for (i = 0; str[i] != '\0'; i++)
 6      str[i] = x;
 7  }
 8
 9  int main(void) {
10    char *s = "abcde";
11    char x = 'X';
12    overwrite(s, x);
13    printf("%s\n", s);
14    return 0;
15  }

gdb调试器告诉我,问题出在第6行,我想将一个char存储到c-string中(如果我使用左值指针解除引用,那就是同样的问题。)这就是他所说的: / p>

(gdb) run
Starting program: /tmp/x/x 

Breakpoint 1, overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:5
5         for (i = 0; str[i] != '\0'; i++)
(gdb) s
6           str[i] = x;
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x080483e3 in overwrite (str=0x8048500 "abcde", x=88 'X') at x.c:6
6           str[i] = x;
(gdb) q

我正在学习K&amp; R-C书籍,这是第2.8章(删除功能)的简化示例。我不知道问题出在哪里。

5 个答案:

答案 0 :(得分:17)

因为char * s =“abcde”;在只读内存中创建字符串。试试

char s[] = "abcde";

编辑:解释:char *是指针,“abcde”是在只读内存中创建的 - &gt;不可变的。

char []是数组,它完全存储在堆栈中并从内存中初始化,因此是可变的

答案 1 :(得分:2)

定义指向字符串文字的指针时,请将其声明为const char *

const char *s = "abcde";

这样,当您尝试将该字符串发送到overwrite()函数时,您的编译器会抱怨。

const char *s = "abcde";
char t[] = "fghij";
char x = 'X';

overwrite(s, x); /* oops */
overwrite(t, x); /* ok */

答案 2 :(得分:1)

不同意,但只是详细说明:考虑一下如果编译器允许这样做会发生什么。你可以写:

char *s1="abcde";
char *s2="abcde";
s1[0]='x';
puts(s1);
puts(s2);

如果编译器识别出两个文字是相同的并重新使用它们,但是也允许第3行,那么你的输出将是:

xbcde
xbcde

这可能不是你想要的。如果两个文字在程序的广泛分离部分中,这将特别神秘。

答案 3 :(得分:-1)

试试:

#include <iostream>
#include <cstring>

using namespace std;

void overwrite(char[], char);

int main(void)
{
        char *s = strdup("abcde");
        char X = 'X';
        overwrite(s, X);
        cout << s << endl;

        if(s!=NULL)
                delete [] s;

        return 0;
}

void overwrite(char str[], char x)
{
        for(int i=0; str[i]!='\0'; i++)
                str[i] = x;
}

答案 4 :(得分:-2)

我的猜测是参数定义,您可以在其中将类型定义为字符数组。当您传递指向char

的指针时

您可以尝试将第一行更改为:

 void overwrite(char *str, char x) {

char数组和char指针在语义上不相同。