将 const char* 分配给 char*

Posted

技术标签:

【中文标题】将 const char* 分配给 char*【英文标题】:Assigning const char* to char* 【发布时间】:2019-12-10 08:33:13 【问题描述】:
#include <cstring>

char* str0;
const char* str1 = "abc";


// assign str1 to str0
strcpy(str0, str1);    // syntax correct, but run time error
str0 = str1;           // syntax error, cannot convert const char* to char*
string n_str = str1;
str0 = n_str;          // syntax error, cannot convert ...


cout << str0 << endl;  // expected output: abc

我想在运行时(编译后)使 str0 与 str1 相同,我不知道该怎么做。对于str0 = str1; 的情况,我不明白为什么它不起作用,因为 str0 指向任何内容,而 str1 指向 const 字符串文字,所以如果我现在让 str0 指向 str1 指向的内容,它应该没关系,但事实并非如此。那么有没有办法解决呢?

【问题讨论】:

strcpy 应该在哪里复制字符串?无处可去?你应该先分配一些内存给str0指向。 要么strdup要么先分配内存。分配不起作用,因为它是 const,您不能通过分配将其删除。 文字字符串(如"abc")实际上是常量字符的数组。为什么你想要一个指向这样一个数组的非常量 char 指针?您需要解决的真正问题是什么?现在这太过分了XY problem。 @Someprogrammerdude 原来的问题是,有一个类,其中一个成员数据为 char* 类型,还有一个构造函数。构造函数具有 const char* 类型的参数之一,构造函数应将成员数据设置为构造函数参数中传递的内容。这是作业的一部分,我不能在网上发布对不起 你不必贴出你的实际代码,只需一个简单的minimal reproducible example 来说明问题,当然也请直接询问实际问题。在这种情况下,您需要为对象中的字符串动态分配内存,并复制内容(并且不要忘记字符串空终止符)。 【参考方案1】:
std::string str0;
const std::string str1 = "abc";

// assign str1 to str0
str0 = str1;

cout << str0 << endl;  // output: abc

如果你坚持使用C:

char* str0;
const char* str1 = "abc";

str0 = malloc(strlen(str1) + 1);
// if you use a c++ compiler you need instead:
// str0 = (char*) malloc(strlen(str1) + 1);

strcpy(str0, str1);

// and free after use
// if you use C++ this will not help much
// as pretty much any exception above will cause your code to get out of `free`,
// causing a memory leak
free(str0);

如果你坚持使用糟糕的 C++:

char* str0;
const char* str1 = "abc";

str0 = new char[strlen(str1) + 1];

strcpy(str0, str1);

// and delete after use
// this will not help much
// as pretty much any exception above will cause your code to get out of `delete`,
// causing a memory leak
delete(str0);

请阅读 RAII 以了解为什么所有手动内存管理的解决方案都不好:cppreference、wiki

【讨论】:

请注意,在C方式中,您应该在之后手动调用free以避免内存泄漏 如果我这样做,并且它有效,它是否与您的解决方案相同? char* str0 = new char; const char* str1 = "abc"; strcpy(str0, str1); @keanehui1 没有。你只为 1 个字符分配内存【参考方案2】:

让我们一次看一个问题

strcpy(str0, str1);

strcpy将str1指向的字符复制到str0指向的内存中。 str1 指向“abc”,但 str0 不指向任何东西,因此出现运行时错误。我建议在任何地方都使用 std::string,这样您就不必自己管理内存。

str0 = str1;  

str0 是 char* 类型,str1 是 const char* 类型。 const 限定符指示编译器不允许对该特定变量进行数据修改(对于 const 的简化角色,更深入的解释使用您最喜欢的搜索引擎,您应该能够找到一堆解释 const 的文章)。如果您能够将相同的指针分配给 str0,您将违反 const 合同; str0 可以修改。

string n_str = str1;

这是有效的,因为 std::string 重载了赋值运算符并接受 const char 指针作为右手值。

str0 = n_str;

n_str 是 std::string 类型,而 str0 是 char*,没有允许这样做的重载运算符。如果您真的想要 std::string 中的原始点,您可以使用 c_str() 方法,它会返回一个 const char* - 我强烈建议您不要这样做,除非您必须将它传递给只接受的函数常量字符*。

【讨论】:

【参考方案3】:

复制strings 是一项昂贵的操作。但是将strings 从一个地方移动到另一个地方是有效的。

抛弃const

str0 = (char*) str1;

或使用std::string 类模板库来管理字符串。 std::string 拥有存储字符串值的字符缓冲区。字符是string 对象的一部分。 cont char* 存储这样一个字符缓冲区的地址,但不拥有它。

c_str 返回一个const char*,它指向一个以空值结尾的字符串。当您想要传递内容时,它很有用。

std::string str1 = "abc";
char* str0;

strcpy(str0, str1.c_str());
printf(str0);

【讨论】:

str1const char *std::stringn_str【参考方案4】:

const 是类型的一部分,因此,您可以将其“丢弃”。这被认为是不好的做法,但您应该将const 视为原始程序员的强烈建议,而不是对其进行修改。

const char * str1 = "abc";
char * str2 = (char*) str1;

【讨论】:

以上是关于将 const char* 分配给 char*的主要内容,如果未能解决你的问题,请参考以下文章

如何将char赋给const char *

c++错误:从不兼容的类型'const char *'分配给'char *'

从 const char 数组初始化为动态分配的 const char 数组

IntelliSense: 不能将 "const char *" 类型的值分配到 "char *" 类型的实体

将'\'分配给char [重复]

双指针将 char 数组值分配给 char 数组,结构使用 char 指针