指向字符串
以下两个代码片段编译时没有任何错误/警告但在运行时崩溃。 请赐教。
计划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”(只读数据)。