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

时间:2010-08-05 04:46:21

标签: c++ string struct malloc

我编写了以下示例程序,但它与segfault崩溃了。问题似乎是在结构中使用mallocstd::string s。

#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;
}

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

谢谢,Boda Cydo。

5 个答案:

答案 0 :(得分:26)

你不能malloc在C ++中使用非平凡构造函数的类。从malloc得到的是 raw 内存块,它不包含正确构造的对象。任何将该内存用作“真实”对象的尝试都将失败。

使用malloc

而不是new对象
example *ex = new example;

您的原始代码也可以强制使用malloc,使用以下一系列步骤:malloc原始内存优先,在第二个原始内存中构造对象:

void *ex_raw = malloc(sizeof(example));
example *ex = new(ex_raw) example;

上面使用的new形式称为“placement new”。但是,在你的情况下,不需要所有这些技巧。

答案 1 :(得分:4)

对于classstruct,例如example,正确的答案是使用new而不是malloc()来分配实例。只有operator new知道如何调用struct及其成员的构造函数。您的问题是由未构造的字符串成员引起的。

然而,有罕见的情况下,特定的内存补丁就好像它拥有一个类的实例一样重要。如果你确实有这种情况,那么operator new的变体允许指定对象的位置。这被称为"placement 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

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

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

总而言之,除非你已经知道你需要一个新的位置,否则你几乎肯定不需要它。它具有合法的用途,但框架有一些模糊不清的角落而不是日常事件。

答案 2 :(得分:3)

使用malloc分配内存不会调用任何构造函数。 不要将C风格的分配与C ++对象混合。他们在一起打得不好。相反,使用new运算符在C ++代码中分配对象:

example *ex = new example;

这是更智能的代码,它将调用std::string::string()构造函数来初始化字符串,这将修复您所看到的段错误。当你完成释放内存并调用适当的析构函数时,不要忘记删除它:

delete ex;

答案 3 :(得分:2)

问题是malloc没有调用example的构造函数。由于string通常表示为堆栈上的指针,因此将其设置为零,并取消引用空指针。您需要改为使用new

答案 4 :(得分:0)

你不应该使用

  

例子* ex =(例子   *)malloc的(的sizeof(* EX));

因为sizeof(* ex)返回的大小等于int的大小或大小,这是由于你的编译周围不同。 您可以使用以下代码:

  

例子* ex =(例子   *)malloc的(的sizeof(实施例));