可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Possible Duplicate:
What is the difference between char s[] and char *s in C?
I initialize a char
pointer:
char *a="test";
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?
---Expanding my question---
If I have initiliazed a
as above and then I do a bunch of other initializations like:
int b=20;
char c[]="blahblahblah";
Can "test" in memory get overwritten with "20" or "blah"? Or does that scenario have no ground?
回答1:
This is dangerous because the string is not-modifiable. Attempting to do so results in undefined behavior.
So it's preferred to do:
const char *a = "test";
You are correct that "test"
in this case is not allocated on the heap or the stack* and instead lies in static memory that is not-modifiable.
*The standard says nothing about the stack or heap, though that's how it's usually implemented.
On the other hand:
char a[] = "test";
Is safe to modify since it's just short-form for:
char a[] = {'t','e','s','t','\0'};
which is an ordinary modifiable array.
回答2:
A literal string in a C program is considered to be read-only and the compiler/linker/loader may arrange for the memory of that string to be in memory that is protected against writing.
Depending on your compiler and OS, the following may trigger a runtime error:
char *a = "test";
a[0] = 'T';
Of course, if you don't actually try to change the string data, then doing this is not dangerous per se. However, it's useful to get the compiler to assist you in ensuring this by declaring the pointer const
:
const char *a = "test";
With this declaration, an attempt to a[0] = 'T'
would be a compile error and would therefore be detected much sooner than runtime.
回答3:
Attempting to modify the contents of a string literal will invoke undefined behavior (meaning anything from a segfault to the code working as expected); it's best to always assume string literals are unwritable.
Thus, as written, a
should not be the target of any function that attempts to modify the string it's pointing to.
** Edit **
The C language definition doesn't say anything about stacks or heaps; it specifies an object's lifetime and visibility, and it's up to the implementation to map that to a specific architecture and memory model. String literals must be allocated so that they're available over the lifetime of the program. Several common architectures put them in a read-only data segment; some put them in a writable data segment. Some allow you to choose which at compile time.
回答4:
All string literals are read-only even though their type may not say so. A string literal's type is char[]
, (for example, "Hello"
is of type char[6]
, one extra for the '\0'
character). Although it is not const
-qualified, the standard says the following in §6.4.5/6:
…If the program attempts to modify such an array, the behavior is
undefined.
If you want a mutable version, you have to either make a copy of the string, or declare it like so:
char a[] = "test";
回答5:
Exactly.
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
回答6:
I have read at some places that this is considered read-only and that it's dangerous.
String literals are indeed read-only.
Does that imply that the "test" is not allocated space in the heap?
Whether the space for the string is allocated is not specified by the standard. It's usually on the static section of the program, but the standard does not even mention things as the heap.
Does that mean that the string "test" can be written over later in the program?
Writing over the string is undefined behavior.
回答7:
String literals like "test"
are read-only and so they cannot be modified. So any attempt to modify them will result in undefined behavior.
For example:
char *a = "test";
*a = 'b';
The *a = 'b';
is an undefined behavior.
So if you want to modify them then you need to use an array
char a[]="test";
So you can modify the "test" to "best" by doing the following:
a[0] = 'b';