当malloc()使用相同的结构时,如何在结构中使用C++字符串?

bod*_*ydo 16 c++ string malloc struct

我编写了以下示例程序,但它与segfault崩溃.问题似乎是在结构中使用malloc和std::strings.

#include <iostream>
#include <string>
#include <cstdlib>

struct example {
 std::string data;
};

int main() {
 example *ex = (example *)malloc(sizeof(*ex));
 ex->data = "hello world";
 std::cout << ex->data << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何让它发挥作用.任何想法,如果它甚至可以使用malloc()和std::strings?

谢谢,Boda Cydo.

AnT*_*AnT 26

你不能malloc在C++中使用非平凡的构造函数.你得到的malloc是一块原始内存,它不包含一个正确构造的对象.任何将该内存用作"真实"对象的尝试都将失败.

而不是malloc-ing对象,请使用new

example *ex = new example;
Run Code Online (Sandbox Code Playgroud)

malloc通过使用以下步骤序列,您的原始代码也可以强制使用:malloc首先是原始内存,然后在该原始内存中构造对象:

void *ex_raw = malloc(sizeof(example));
example *ex = new(ex_raw) example;
Run Code Online (Sandbox Code Playgroud)

new上面使用的形式称为"放置新".但是,在你的情况下,不需要所有这些诡计.

  • @bodacydo:您可以使用 `new(std::nothrow) example` 来让 `new` 返回空指针而不是抛出异常。您必须包含标头 `&lt;new&gt;` 才能使用 `std::nothrow` 常量。 (2认同)
  • @bodacydo:如果你真的希望“new”在失败时返回空指针,请使用“new(nothrow) example”。但实际上你应该使用“try”/“catch”来捕获任何抛出的异常。(例如,如果未能分配内存,“std::string”赋值也可能引发异常。) (2认同)

RBe*_*eig 6

对于像您这样的class或,正确的答案是不分配实例。只知道如何调用 及其成员的构造函数。您的问题是由尚未构造的字符串成员引起的。structexamplenewmalloc()operator newstruct

然而,在极少数情况下,特定的内存块就像保存了类的实例一样,这一点很重要。如果确实有这种情况,那么有一种变体operator new允许指定对象的位置。这称为“新放置”,必须小心使用。

void *rawex = malloc(sizeof(example));  // allocate space
example ex = new(rawex) example();      // construct an example in it
ex->data = "hello world";               // use the data field, not no crash
// time passes
ex->~example();                         // call the destructor
free(rawex);                            // free the allocation
Run Code Online (Sandbox Code Playgroud)

通过使用placement new,您有义务提供正确大小和对齐方式的内存区域。不提供正确的尺寸或对齐方式会导致神秘的事情出错。不正确的对齐通常会更快地导致问题,但也可能很神秘。

此外,对于新的放置,您需要负责手动调用析构函数,并根据内存块的来源将其释放给其所有者。

总而言之,除非您已经知道需要新的展示位置,否则您几乎肯定不需要它。它有合法的用途,但框架中存在一些模糊的角落,而不是日常发生的情况。