C语言 char *str="STRING" 和 char str[] = "STRING" 的区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3862842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between char *str="STRING" and char str[] = "STRING"?
提问by Gui13
While coding a simple function to remove a particular character from a string, I fell on this strange issue:
在编写一个简单的函数来从字符串中删除特定字符时,我遇到了这个奇怪的问题:
void str_remove_chars( char *str, char to_remove)
{
if(str && to_remove)
{
char *ptr = str;
char *cur = str;
while(*ptr != 'char ptr[] = "string";
')
{
if(*ptr != to_remove)
{
if(ptr != cur)
{
cur[0] = ptr[0];
}
cur++;
}
ptr++;
}
cur[0] = 'char *ptr = "string";
';
}
}
int main()
{
setbuf(stdout, NULL);
{
char test[] = "string test"; // stack allocation?
printf("Test: %s\n", test);
str_remove_chars(test, ' '); // works
printf("After: %s\n",test);
}
{
char *test = "string test"; // non-writable?
printf("Test: %s\n", test);
str_remove_chars(test, ' '); // crash!!
printf("After: %s\n",test);
}
return 0;
}
What I don't get is why the second test fails?
To me it looks like the first notation char *ptr = "string";is equivalent to this one: char ptr[] = "string";.
我不明白的是为什么第二次测试失败?对我来说,第一个符号看起来char *ptr = "string";等同于这个符号:char ptr[] = "string";。
Isn't it the case?
不是这样吗?
回答by codaddict
The two declarations are not the same.
这两个声明是不一样的。
char ptr[] = "string";declares a char array of size 7and initializes it with the characterss,t,r,i,n,gand \0. You are allowedto modify the contents of this array.
char ptr[] = "string";声明一个大小为 char 的数组,7并用字符s, t, r, i, n,g和初始化它\0。您可以修改此数组的内容。
char *ptr = "string";declares ptras a char pointer and initializes it with address of string literal"string"which is read-only. Modifying a string literal is an undefined behavior. What you saw(seg fault) is one manifestation of the undefined behavior.
char *ptr = "string";声明ptr为字符指针与地址初始化字符串文字"string"这是只读的。修改字符串文字是一种未定义的行为。您所看到的(段错误)是未定义行为的一种表现。
回答by PP.
Strictly speaking a declaration of char *ptronly guarantees you a pointer to the character type. It is not unusual for the string to form part of the code segment of the compiled application which would be set read-only by some operating systems. The problem lies in the fact that you are making an assumption about the nature of the pre-defined string (that it is writeable) when, in fact, you never explicitly created memory for that string yourself. It is possible that some implementations of compiler and operating system will allow you to do what you've attempted to do.
严格来说,声明char *ptr只保证你有一个指向字符类型的指针。字符串构成已编译应用程序的代码段的一部分并被某些操作系统设置为只读的情况并不少见。问题在于您对预定义字符串的性质(它是可写的)做出了假设,而事实上,您自己从未明确为该字符串创建内存。编译器和操作系统的某些实现可能会允许您执行您尝试执行的操作。
On the other hand the declaration of char test[], by definition, actually allocates readable-and-writeable memory for the entire array of characters on the stack in this case.
另一方面char test[],根据定义,在这种情况下,的声明实际上为堆栈上的整个字符数组分配了可读和可写的内存。
回答by Naveen
char *test = "string test";is wrong, it should have been const char*. This code compiles just because of backward comptability reasons. The memory pointed by const char*is a read-only memory and whenever you try to write to it, it will invoke undefined behavior. On the other hand char test[] = "string test"creates a writablecharacter array on stack. This like any other regualr local variable to which you can write.
char *test = "string test";错了,应该是const char*。这段代码编译只是因为向后兼容性的原因。指向的内存const char*是只读内存,每当您尝试写入时,它都会调用未定义的行为。另一方面,在堆栈上char test[] = "string test"创建一个可写的字符数组。这就像您可以写入的任何其他常规局部变量一样。
回答by DerKuchen
As far as I remember
就目前我所记得的
const char *ptr = "string";
creates a copyof "string"on the stack, so this one is mutable.
创建副本的"string"堆栈上,所以这一块是可变的。
The form
表格
char *str = strdup("test");
str[0] = 'r';
is just backwards compatibility for
只是向后兼容
##代码##and you are not allowed (in terms of undefined behavior) to modify it's content. The compiler may place such strings in a read only section of memory.
并且您不得(就未定义行为而言)修改其内容。编译器可能会将此类字符串放在内存的只读部分中。
回答by Prof. Falken contract breached
Good answer @codaddict.
很好的答案@codadd。
Also, a sizeof(ptr)will give different results for the different declarations.
此外,asizeof(ptr)将为不同的声明提供不同的结果。
The first one, the array declaration, will return the length of the array includingthe terminating null character.
第一个,数组声明,将返回数组的长度,包括终止的空字符。
The second one, char* ptr = "a long text...";will return the length of a pointer, usually 4 or 8.
第二个,char* ptr = "a long text...";将返回指针的长度,通常为 4 或 8。
回答by Ravi Chandra
is proper code and creates a mutable string. str is assigned a memory in the heap, the value 'test' filled in it.
是正确的代码并创建一个可变字符串。str 在堆中分配了一块内存,值 'test' 填入其中。

