2011-12-30 220 views
0

以下两个代码片段编译时没有任何错误/警告,但运行时崩溃。请赐教。指向字符串的指针

程序1个

int main() 
{ 
    char *p= "Hello" ; 

    *p = 'B' ; 
    printf("\n%s",p); 

    return 0; 
} 

计划2

int main() 
{ 
    char *p= "Hello" ; 
    Char *q="mug" 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 

对于节目2 I期望输出是 '拥抱'。

回答

8

当你这样做:

char *p= "Hello"; 

您正在定义一个字符串。字符串文字是不变的数据,正如你发现的那样,修改它们会导致未定义的行为(通常是崩溃)。它应该被声明为:

const char *p = "Hello"; 

因此,如果您尝试修改它,编译器会引发错误。

现在,如果你定义它不是作为:

char p[] = "Hello"; 

的内存,然后在栈上分配的,你可以修改它。

int main(int argc, char *argv[]) 
{ 
    char p[] = "Hello" ; 

    *p = 'B' ; 
    printf("\n%s",p); 

    return 0; 
} 

输出Bello

的方案2,注意只q需要在堆栈上。 p可以保持指向字符串文字的const指针,因为您只是从中读取数据。

int main() 
{ 
    const char *p = "Hello" ; 
    char q[] = "mug"; 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 

输出Hug

+0

乔感谢队友 – intex0075 2011-12-30 18:13:25

+0

@ intex0075很高兴帮助,并感谢接受。 – JoeFish 2011-12-30 18:16:10

0

在这两个示例中,您正在修改字符串文字,这会产生未定义的行为。

0

你应该写的是:

char p[] = "Hello"; 

上面的表格(字符P [] =“你好”)告诉编译器,“我有值的来了一个阵列,请分配尽可能多的他们需要的空间。“它也适用于整数,例如:

int i [] = { 1, 2, 5, 100, 50000 }; 

您将最终与我是一个指向5值的数组的指针。

+0

是的,我意识到不久之后,我发布并删除它。对困惑感到抱歉。 – user1118321 2011-12-30 18:01:06

0

当您以char * p =“test”的形式创建静态字符串时,指针的内容无法更改。在你的情况下,试图修改指针的内容会导致你正在观察的错误。

0

我将程序2更改为不使用字符串文字。它显示“拥抱”,如你所料。

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

int main() 
{ 
    char p[10]; 
    char q[10]; 
    strcpy(p,"Hello"); 
    strcpy(q,"mug"); 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 
+0

这是一个答案? – 2011-12-30 17:59:12

+0

已经有4个答案为什么代码失败了。这个答案解释了如何做对。 – 2011-12-30 18:02:38

0

字符串“你好”和“杯子”存储在只读存储器和你试图写在那里。

$ gcc -S a.c 
$ cat a.s 
    .file "a.c" 
    .section  .rodata 
.LC0: 
    .string "Hello" 
.LC1: 

请注意,该部分是“rodata”(只读数据)。

+0

Atom是否表示文字存储在“代码/文本片段”中。这就是为什么它变成RO? – intex0075 2011-12-30 18:14:50

+0

文字存储在包含数据(不是代码)的部分“.rodata”中,ELF可执行文件中的标志表示该部分是只读的。还有其他部分,如“.text”和“.data”。您可以使用“readelf --sections executable_file”打印所有部分,“Flg”列指定部分的访问权限。 – 2011-12-30 18:24:38