在C中初始化char指针

Initializing a char pointer in C. Why considered dangerous?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is the difference between char s[] and char *s in C?

初始化char指针:

1
char *a="test";

我在一些地方读到,这被认为是只读的,而且很危险。

这是否意味着"test"不是堆中分配的空间?这是否意味着字符串"test"可以稍后在程序中写入?

——扩大我的问题---

如果我像上面一样初始化了a,那么我会进行一些其他初始化,比如:

1
2
int b=20;
char c[]="blahblahblah";

内存中的"test"会被"20"或"blah"覆盖吗?或者这种情况没有根据?


这很危险,因为字符串不可修改。尝试这样做会导致未定义的行为。

所以最好这样做:

1
const char *a ="test";

在这种情况下,不在堆或堆栈*上分配"test",而是在不可修改的静态内存中,这是正确的。

*虽然通常是这样实现的,但标准对堆栈或堆没有任何说明。

另一方面:

1
char a[] ="test";

修改是安全的,因为它只是用于:

1
char a[] = {'t','e','s','t','\0'};

它是一个普通的可修改数组。


尝试修改字符串文字的内容将调用未定义的行为(意味着从segfault到按预期工作的代码的任何内容);最好始终假定字符串文字是不可写的。

因此,正如所写,a不应该是任何试图修改其所指向字符串的函数的目标。

**编辑**

C语言的定义没有提到栈或堆;它指定了一个对象的生存期和可见性,而将其映射到一个特定的体系结构和内存模型则取决于实现。必须分配字符串文本,以便它们在程序的生命周期内可用。几个常见的体系结构将它们放在只读数据段中;一些将它们放在可写数据段中。有些允许您在编译时选择哪个。


C程序中的文本字符串被认为是只读的,编译器/链接器/加载器可以将该字符串的内存安排在受写保护的内存中。

根据编译器和操作系统的不同,以下内容可能会触发运行时错误:

1
2
char *a ="test";
a[0] = 'T';

当然,如果您实际上没有尝试更改字符串数据,那么这样做本身并不危险。但是,让编译器通过声明指针EDOCX1[1]来帮助您确保这一点很有用:

1
const char *a ="test";

有了这个声明,对a[0] = 'T'的尝试将是一个编译错误,因此将比运行时更快地被检测到。


"test"这样的字符串文本是只读的,因此不能修改。因此,任何修改它们的尝试都将导致未定义的行为。

例如:

1
2
char *a ="test";
*a = 'b';

*a = 'b';是一种未定义的行为。

因此,如果要修改它们,则需要使用数组

1
char a[]="test";

因此,您可以通过执行以下操作将"测试"修改为"最佳":

1
a[0] = 'b';

I have read at some places that this is considered read-only and that it's dangerous.

字符串文本确实是只读的。

Does that imply that the"test" is not allocated space in the heap?

标准未指定是否为字符串分配空间。它通常在程序的静态部分,但是标准甚至没有提到堆。

Does that mean that the string"test" can be written over later in the program?

写入字符串是未定义的行为。


确切地。

For instance the string defined by char s[] ="hello world" in C and a C statement like int debug=1 outside the"main" would be stored in initialized read-write area. And a C statement like const char* string ="hello world" makes the string literal"hello world" to be stored in initialized read-only area and the character pointer variable string in initialized read-write area. Ex: static int i = 10 will be stored in data segment and global int i = 10 will be stored in data segment


所有字符串文本都是只读的,即使它们的类型不能这样说。字符串文字的类型是char[](例如,"Hello"char[6]类型,'\0'字符多加一个)。虽然该标准不符合const的要求,但在§;6.4.5/6中规定如下:

…If the program attempts to modify such an array, the behavior is
unde?ned.

如果您想要一个可变的版本,您必须复制一个字符串,或者像这样声明它:

1
char a[] ="test";