如何最好地在c ++中分配动态内存

时间:2014-12-07 13:22:28

标签: c++ templates generics

这对于c ++中的类和模板的内存分配更好。 malloc()或new;可以使用malloc()为类或模板分配内存吗?

2 个答案:

答案 0 :(得分:2)

可以这样做,虽然不是你这样做的方式,但无论如何它并不是真正的初学者。你的方法不起作用的原因是未初始化的内存块与有效对象不同。但在我继续之前:

重要风格注意:为了简洁起见,我将暂时放在一边,通常的记忆管理机制(智能指针等)你应该坚持作为初学者虔诚地坚持(事实上,作为专家,但他们不需要被告知)。不要使用类似于我将要在生产中展示的代码(不是没有所有必要的簿记),或者以可调试的方式破解。我只是这样做,因为正确地做它会掩盖我试图展示的机制。

从广义上讲,未初始化内存块和有效对象之间的区别是类不变量。这意味着一个类定义了它们始终满足的对象的某些属性。例如,字符串类通常会保证指向其数据的指针不会是悬空指针,并且不会报告其大小大于指针指向的内存块。未初始化的内存块不能保证这些内容,这就是为什么我们有构造函数。构造函数是一个函数,它将对象构造成一个未初始化的内存块,修复这些不变量,并且大多数时候它会自动为您调用。如果你写

Foo f;

内存是从堆栈中获得的(简化术语;请加上我,语言律师),并在该段内存上调用默认构造函数Foo::Foo()。同样,如果你写

Foo *p = new Foo();

operator new从堆中获取内存并调用该内存中的构造函数。可能它不止于此,但让我们暂时放下这种可能性。

那你的代码出了什么问题?那么,当你写

*obj = A();

这是一项任务。它假定有一个有效的对象*obj,可以将新构造的对象复制到其中。情况并非如此,因为obj指向未初始化的内存块。

所以,在你可以像对象一样使用未初始化的内存块之前,你必须在其中构造一个。这是可能的,它被称为展示位置新。语法如下所示:

new(obj) A();

之后你必须手动调用析构函数(构造函数的对应函数;其目的是撤消构造函数的作用):

obj->~A();

...之后obj将再次指向未初始化的内存,并且(除非该类是错误的)所有必要的清理工作已经完成。除了回馈内存块,因为它是在构造函数/析构函数duo之外分配的。通常它会在范围的末尾自动发生(对于像f这样的自动变量)或delete会为你做(对于像*p这样的动态存储对象),但是你自己做了分配,你必须自己进行解除分配。

答案 1 :(得分:1)

应避免使用malloc()用于allocatiog C ++对象。

使用C ++练习重写main()

A *obj = new A();  // get memory and initialize the object 
B<int> *objb = new B<int>();  // same 

这更好用,更容易阅读!

备注: *obj=A();之类的语句可能会调用特定于类的赋值运算符,该运算符会假设已*obj已初始化构造函数并处于有效状态。如果malloc()简单地获取了内存,则不会满足此假设。