指向字符串

以下两个代码片段编译时没有任何错误/警告但在运行时崩溃。 请赐教。

计划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,我预计输出为’Hug’。

当你这样做时:

 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

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

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

我将程序2更改为不使用字符串文字。 它显示了你所期望的“拥抱”。

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

你应该写的是:

 char p[] = "Hello"; 

上面的表单(char p [] =“Hello”)告诉编译器,“我有一个值数组,请为它们分配尽可能多的空间。” 它也适用于整数,例如:

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

你最终会得到一个指向5个值数组的指针。

字符串“Hello”和“mug”存储在只读存储器中,您正在尝试写入。

 $ gcc -S ac $ cat as .file "ac" .section .rodata .LC0: .string "Hello" .LC1: 

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