在c ++中这是一个使用字符串文字初始化char数组的好习惯吗?

时间:2015-05-12 17:47:27

标签: c++

在c ++中

这是一个用字符串初始化char数组的好习惯吗? 如:

char* abc = (char *) ("abcabc");

我在同事的代码中看到了很多这些。我应该改变它吗? 比如

std::string abc_str = "abcabc";
const char* abc= abc_str .c_str();

3 个答案:

答案 0 :(得分:12)

本声明

char* abc = (char *) ("abcabc");

简直太糟糕了。 C ++中的字符串文字具有常量字符数组的类型。所以有效的声明看起来像

const char *abc = "abcabc";

注意:在C中你确实可以写

char *abc = "abcabc";

然而,字符串文字是不可变的。任何修改字符串文字的尝试都会导致未定义的行为。

顺便说一句,没有任何由字符串文字初始化的字符数组。:)也许你的意思是以下

char abc[] = "abcabc";

使用标准类std::string不排除使用字符数组以及指向字符串文字的指针。

考虑到这些声明

const char *abc = "abcabc";

std::string abc_str = "abcabc";
const char* abc= abc_str .c_str();

不等同。相对于第一个声明字符串文字具有静态存储持续时间,并且在程序执行期间它们的地址不会更改。 在第二个声明中,指针abc指向动态分配的内存,如果对象abc_str将被更改,则可以重新分配该内存。在这种情况下,指针将无效。

此外,第一个声明假设指针指向的数组(字符串文字)不会被更改。在第二个声明中,假设将更改std :: string类型的对象。否则,声明一个std :: string类型的对象而不是指针是没有意义的。

因此,声明的含义完全不同。

答案 1 :(得分:5)

char* abc = (char *) ("abcabc");

这很糟糕。不要这样做。

您正在处理一个不应修改的字符串文字,因为它可以被修改。

之后,

abc[0] = 'd';

编译器可以正常,但在运行时不正常。你需要使用的是:

char abc[] = "abcabc";

这将创建一个可修改的数组。

答案 2 :(得分:3)

这两个都不好。

char* abc = (char*) ("abcabc");

字符串文字是常量,因此可以存储在写保护的内存中。因此,写入它可能会使程序崩溃,这是未定义的行为。

如果你想编辑它的内容,你应该保留它const并制作副本,而不是丢弃 constness

const char* abc = "abcabc";

另一个也应该避免:

std::string abc_str = "abcabc";
const char* abc = abc_str.c_str();

保持const是好的但是如果字符串被更改,它可以被重新分配到内存中的另一个地方,让你的指针悬空。

同样在前C++11代码中,指针在指定的第二个指针时停止有效,因为无法保证指针不是临时指针。

最好每次都致电abc_str.c_str()

可能因为c_str()是如此微不足道的操作,它将被编译器优化掉,使其与使用原始指针一样高效。

而不是应该正在做的那些事情,而不是一直使用std::string。如果您完全需要 const char*(对于旧的遗留代码),您可以使用c_str()获取它。

std::string abc_str = "abcabc"; // this is perfect why do more?

old_horrible_function(abc_str.c_str()); // only when needed