【问题标题】:Assigning const char* to char*将 const char* 分配给 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 来说明问题,当然也请直接询问实际问题。在这种情况下,您需要为对象中的字符串动态分配内存,并复制内容(并且不要忘记字符串空终止符)。

标签: c++ string pointers


【解决方案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 以了解为什么所有手动内存管理的解决方案都不好:cppreferencewiki

【讨论】:

  • 请注意,在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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      相关资源
      最近更新 更多