将 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);
【讨论】:
str1
是const char *
。 std::string
是 n_str
。【参考方案4】:
const
是类型的一部分,因此,您可以将其“丢弃”。这被认为是不好的做法,但您应该将const
视为原始程序员的强烈建议,而不是对其进行修改。
const char * str1 = "abc";
char * str2 = (char*) str1;
【讨论】:
以上是关于将 const char* 分配给 char*的主要内容,如果未能解决你的问题,请参考以下文章
c++错误:从不兼容的类型'const char *'分配给'char *'
从 const char 数组初始化为动态分配的 const char 数组