【问题标题】:Assigning values to Char* within structure which solution is desirable c++在需要解决方案的结构中为 Char* 赋值 c++
【发布时间】:2015-01-26 02:15:27
【问题描述】:

让我说我有一个充满字符指针的结构。使用从函数返回的字符串初始化值的正确方法是什么

typedef struct details{
char *name;
char *address;
char *nickname;
}details_t

string function() 
{
string name = "random string calculation";
return string;
}

案例1:

直接分配返回值。这里我不明白 string_1.c_str() 的结果存储在哪里。它是在堆中,因为它是字符串类吗?

main()
{
details_t details_t1;
details_t1.name = function().c_str();
details_t1.address = function().c_tr();

function_2(details_t1);
}

案例 2: 在堆中分配内存

main()
{
details_t details_t1;
details_t1.name = (char*)malloc(string_1.size()+1);
strcpy(details_t1.name,string_1.c_str();
....

function_2(details_t1);
}

【问题讨论】:

  • C 已经要求函数的显式返回类型已经有一段时间了...但是,我不建议使用 string_1.c_str(),因为从该函数返回的 C 字符串只保证存在,只要string_1 存在。
  • 你为什么还要在 C++ 程序中使用 C 风格的 char * 字符串?只需始终使用std::string - 它会让生活变得更轻松。
  • “string_1.c_str() 的结果存储在哪里” - 结果是一个 const char*,它存储在你的结构中。但是,它指向的数据仍存储在std::string 中。因此,当字符串超出范围时,结构中的指针不会指向任何内容。
  • 不可能在不知道你在用这个结构做什么的情况下给你明确的建议。
  • 它确实有字符串的c_str,它是C++

标签: c++ c struct char


【解决方案1】:

c_str()string 类当前具有字符的任何位置 - 它可能在堆上,它可能正在使用小字符串优化。如果字符串被更新,它可能会改变,因为 C++ 字符串不是不可变的。它可能会超出范围。 不要使用选项 1。

选项 2 更安全。然后,您在结构中拥有自己的副本。 但是,不要忘记之后释放内存。 如果你可以做 C++,使用析构函数来整理。 然后考虑复制构造函数等(规则 3 或 5)。

选项 3 可能会更好: 考虑只在里面放std::strings。 (0 规则)

【讨论】:

  • 在某些情况下选项 1 是最好的,例如二进制互操作。我们对结构的使用知之甚少,无法确定。
  • 你是对的,当然。我们也不知道为什么我们有这个 C 结构,以及我们是否可以像我和 Wojtek 的回答所说的那样改变它。
  • @doctorlove:我现在正在使用第二个选项,因为我知道使用 .c_str() 函数是危险的,以防字符串超出范围或字符串位置更改或值得到更新
【解决方案2】:

两种情况都是错误的:

  1. 您存储由c_str 返回的指针。该指针的生命周期由返回它的字符串控制,因此它独立于details_t 结构。您可能引用的内存区域不再有效,因为例如您将向字符串附加一些内容,它将重新分配其内部缓冲区,并且您的结构仍将指向旧缓冲区。

  2. 您正在使用 malloc 分配内存(在 C++ 中几乎总是错误的)并将此内存分配给结构的成员。这在技术上并非不正确,但这不是 C++ 中的处理方式。将结构成员分配给未知所有者的分配内存是不行的。

你应该忘记在你的结构中使用char*,而只使用std::string

【讨论】:

  • c_str() 版本可能是正确的,如果该结构用于与其他库进行互操作,并且在修改字符串之前返回调用的函数。
  • 嗨,我正在使用 malloc(),因为我正在接口的模块是用 c 实现的,尽管我的实现是用 c++ 实现的
  • @DavidHeffernan :我没有明白这一点“在修改字符串之前调用的函数返回”
  • c_str()返回的C字符串只有在字符串被修改之前有效。所以如果你像这样填充结构,然后立即调用外部函数,你会没事的。您问题中的巨大遗漏是对您对结构所做的任何解释。没有这些信息,您将无法获得非常具体的建议。
  • @vinotheswaran 您正在连接的模块是否释放内存?如果不是,则不需要使用malloc - 内存就是内存,C 模块不关心它是如何分配的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2017-05-27
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
  • 2017-10-02
相关资源
最近更新 更多