可能重复:
What is the difference between char s[] and char *s in C?
我初始化一个char
指针:
char *a="test";
我在某些地方读到这被认为是 只读 ,这很危险。
这是否意味着"test"
没有在堆中分配空间?这是否意味着字符串“test”可以在以后的程序中写出来?
---扩展我的问题---
如果我已按上述方式初始化a
,那么我会进行一系列其他初始化,例如:
int b=20;
char c[]="blahblahblah";
内存中的“测试”是否会被“20”或“blah”覆盖?或者这种情况没有根据?
答案 0 :(得分:14)
这很危险,因为字符串不可修改。尝试这样做会导致 未定义的行为 。
所以最好这样做:
const char *a = "test";
你是正确的,在这种情况下"test"
没有在堆或堆栈*上分配,而是位于不可修改的静态内存中。
*标准对堆栈或堆没有任何说明,尽管这通常是如何实现的。
另一方面:
char a[] = "test";
可以安全修改,因为它只是简短形式:
char a[] = {'t','e','s','t','\0'};
这是一个普通的可修改数组。
答案 1 :(得分:1)
C程序中的文字字符串被认为是只读的,编译器/链接器/加载程序可以将该字符串的内存安排在内存中,以防止写入。
根据您的编译器和操作系统,以下内容可能会触发运行时错误:
char *a = "test";
a[0] = 'T';
当然,如果您实际上并未尝试更改字符串数据,那么这样做本身并不是危险。但是,让编译器通过声明指针const
来帮助您确保这一点很有用:
const char *a = "test";
使用此声明,尝试a[0] = 'T'
将是编译错误,因此将比运行时更快地检测到。
答案 2 :(得分:1)
尝试修改字符串文字的内容将调用未定义的行为(意味着从段错误到代码按预期工作);最好总是假设字符串文字是不可写的。
因此,正如所写的那样,a
不应该是任何试图修改它所指向的字符串的函数的目标。
**编辑**
C语言定义没有说明堆栈或堆;它指定了对象的生命周期和可见性,并且由实现将其映射到特定的体系结构和内存模型。必须分配字符串文字,以便它们在程序的生命周期内可用。几种常见的体系结构将它们放在只读数据段中;有些人把它们放在一个可写的数据段中。有些允许您在编译时选择哪个。
答案 3 :(得分:0)
所有字符串文字都是只读的,即使它们的类型可能不是这样。字符串文字的类型为char[]
,(例如,"Hello"
的类型为char[6]
,'\0'
字符的一个额外值。虽然它不是const
- 合格,但标准在§6.4.5/ 6中说明如下:
...如果程序试图修改这样的数组,行为是 理解过程科幻奈德。
如果你想要一个可变版本,你必须复制一个字符串,或者像这样声明它:
char a[] = "test";
答案 4 :(得分:0)
例如,由C中的
中char s[] = "hello world"
定义的字符串和“main”之外的int debug=1
之类的C语句将存储在初始化的读写区域中。像const char* string = "hello world"
这样的C语句使字符串文字“hello world”存储在初始化的只读区域中,字符指针变量字符串存储在初始化的读写区域中。例如:static int i = 10
将存储在数据段中,global int i = 10
将存储在数据段
答案 5 :(得分:0)
我在某些地方读到这被认为是只读的,这很危险。
字符串文字确实是只读的。
这是否意味着“测试”没有在堆中分配空间?
标准是否指定了是否分配了字符串的空间。它通常在程序的静态部分,但标准甚至没有提到堆。
这是否意味着字符串“test”可以在以后的程序中写出来?
写字符串是未定义的行为。
答案 6 :(得分:0)
"test"
之类的字符串文字是只读的,因此无法修改它们。因此,任何修改它们的尝试都将导致未定义的行为。
例如:
char *a = "test";
*a = 'b';
*a = 'b';
是未定义的行为。
因此,如果您想修改它们,则需要使用数组
char a[]="test";
因此,您可以通过执行以下操作将“测试”修改为“最佳”:
a[0] = 'b';