2009-09-10 73 views
3

我的代码段错误,我不知道为什么。写入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-字符串(如果我用左值指针引用,这是同样的问题。)这是什么他说:

(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 & RC本书的学习,这从章节2.8(删除功能)简化的例子。我不知道问题在哪里。

回答

17

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

char s[] = "abcde"; 

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

炭[]是数组,其被完全存储在栈和从存储器初始化,因此是可变的

-2

我的猜测是在其中定义类型作为字符数组的参数定义。当你在一个指针传递给一个char

你可以尝试改变第一行是:

void overwrite(char *str, char x) { 

字符数组和字符指针是语义不相同。

+0

'炭STR []'和'字符* str'是等价作为函数参数。 – sepp2k 2009-09-10 14:34:16

+0

你错了,在参数列表中使用时,char str []会衰减到char *'。 – avakar 2009-09-10 14:35:33

+0

好的....但我是对的,他们在某些情况下是不同的权利?你能否详细说明在不同的情况下? – Toad 2009-09-10 14:36:23

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 */ 
1

并不意见,但只是为了阐述:考虑如果编译器允许这样做会发生什么。你可以写:

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

如果编译器识别出两个字符串是相同的,并重新使用它们,但后来也允许线3条,你的输出将是:

xbcde 
xbcde 

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

+0

这就是为什么.Net字符串是不可变的。它*通过称为“字符串实习”的东西来重用字符串。 – 2009-09-10 15:20:36

+0

@Tom Ritter - 是的,这就是为什么.Net是一个完全不同的平台,其目标完全不同于C。 – 2009-09-11 05:14:18

-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; 
} 
+0

问题被标记为C ...并且如果您要检查s为NULL,您可以在strdup()调用,而不是使用无效指针。 – pmg 2009-09-10 16:36:02

+0

也strdup做一个malloc()...调用delete []是错误的。 – Nicholaz 2009-11-17 14:37:30