我编写了以下示例程序,但它与segfault崩溃了。问题似乎是在结构中使用malloc
和std::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。
答案 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)
对于class
或struct
,例如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(实施例));