在C ++中,为什么编译器不允许修改以下字符指针,如下所示
#include <iostream>
int main()
{
char* cp = "overflow";
cp[1]='p';
return 0;
}
输出:在运行时崩溃。
但是字符数组允许,
#include <iostream>
int main()
{
char cps[] = "overflow";
cp[1]='p'; // this compiles fine and output is operflow
return 0;
}
只是想知道运行时发生了什么以及崩溃的原因。谢谢。
答案 0 :(得分:9)
字符串文字是char const[]
类型的左值,其中const
是重要的部分。尝试修改类型为const
的对象未定义行为。
根据C ++ 11标准的第2.14.5 / 8段:
普通字符串文字和UTF-8字符串文字也称为窄字符串文字。 狭窄 string literal的类型为“ n
const char
”的数组,其中 n 是下面定义的字符串的大小,并且 静态存储时间(3.7)。
在第二种情况下(假设您的意思是char cps[] = "overflow";
,带方括号),您正在初始化字符串文字的非const
副本。修改该副本是可以的。
另请注意,在C ++ 03中不推荐从字符串文字转换为非-const
char *
,在C ++ 11中不推荐使用非法。另一方面,这是合法的:
char const* cp = "overflow";
// ^^^^^
答案 1 :(得分:2)
这个:char* str="";
,是一个字符串文字,可能存储在内存的只读部分,因此可能会崩溃。使用const char* const str="string";
(指针和数据都是常量或至少数据应该是常量:const char* str="string";
或char const* str="string";
)
如果您尝试更改字符串文字的内容,则会出现未定义的行为和分段错误,从而导致崩溃。
答案 2 :(得分:0)
当你设置char* cp = "overflow";
时,你正在创建一个只读的内存块,其中包含"overflow"
(后跟一个NULL终止字节),所以你不能在那里写。试图更改c[x]
需要在那里写作。
至于你的第二段代码 - 缺少一些东西,以至于部分问题不清楚。
答案 3 :(得分:0)
因为指向字符的指针不是array
和low-level const
。你可以做到
char cp[] = {'o', 'v', 'e', 'r', 'f', 'l', 'o', 'w', '\0'};
char *pcp = cp;
*++pcp = 'p';
但是,"overflow"
是一个不可修改的常量字符序列,因此您只能执行指针算术并取消引用值的指针。
char *cp = "overflow";
std::cout << *++cp std::endl;