文字字符串赋值悖论

时间:2014-04-25 17:45:22

标签: c++11

为什么要将文字字符串分配给可变字符数组,如

char * p = "Hello World!\n";

在将文字字符串传递给函数参数(如

)时会产生警告
void function foo(char* p) {
  //do stuff
}

int main() {
  foo("Hello World!\n");
}

不会产生警告

我来自红宝石之地,所有这一切都是为我做的大声笑我为我一个大胆的新世界感谢帮助我理解

1 个答案:

答案 0 :(得分:1)

如果我编译你的程序,我会收到两次警告,这是我所期望的。指针赋值和带字符串文字的直接函数调用给出:

 warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

实际上这个警告应该被视为错误,因为你无法改变指针指向的内容。如果您尝试修改foo()中的内容,则运行

void foo(char* p)
{
  p[0]='n';
}

导致异常,这是我们所期望的!

问题不是函数foo而是init到const数组。

如果您将代码更改为:

void foo(char* p) {
    p[0]='n';
}   

int main() {
    char * from = "Hello World!\n";
    char * to = new char[100]; // enough space to put the string here
    strcpy( to, from );
    foo( to );
    foo( from );
    cout << to << endl;
 }   

并在调试器中运行,程序在foo( from );

行崩溃

你应该做的事情:

如果您的函数不会修改指针指向的内容,请将pointer改为const pointer

如果你的程序必须修改指针指向的内容,你必须使用你可以写的内存。

一个简单的改变可以完成这项工作:

int main() {
    char from[]= "Hello World!\n";   
    //char* from= "Hello World!\n";
    foo( from );
    cout << from << endl;
} 

这里的区别是:

from现在是堆栈上的一个数组,位于函数main的本地。您可以在函数foo()中修改自己的数组。

我的提示:如果您看到将const值传递给非常量指针的警告,请将此值始终视为错误,而不仅仅是警告。这只是一个警告,而大量的旧代码将不再编译。但请记住:对const值的写访问始终是未定义的行为,通常是崩溃。