这个内存分配在哪里分配?

时间:2016-08-28 20:51:22

标签: c++ memory-management

以下是代码行:

A a = static_cast<A>(*(new A)); // ?

至少在64位铿锵声中编译好。

但实际分配的内存在哪里以及变量a会发生什么?

4 个答案:

答案 0 :(得分:4)

除了不需要静态强制转换之外,分配有new A的内存只是泄漏。您已经失去了对该指针的访问权限,并且永远不能delete正确使用它。

  

但实际分配的内存在哪里以及变量a会发生什么?

变量a会在像往常一样离开范围时被销毁。

答案 1 :(得分:2)

A a = static_cast<A>(*(new A)); // ?

这样做如下。

(new A) // allocate a new A on the heap

*(new A) // the type is now A instead of *A

static_cast<A>(*(new A)) // makes it into an type A from type A in an potentially unsafe way (here it is a no-op as they are the same type)

A a = static_cast<A>(*(new A)); // copies the (default) value of A to a

; // leaks the allocted A as the last reference to it disappear.

答案 2 :(得分:1)

我假设这行代码出现在一个函数中,我将回答这个问题。如果它出现在其他地方,关于&#34;堆栈&#34;是不准确的,但其他一切仍然准确。

这行代码编译为四个操作,我们可以将它们编写为自己的C ++行,以使事情更清晰。它在两个不同的地方进行两个分配,其中一个是&#34;泄露&#34;。

A a;
{
    A *temp = new A;
    a = *temp;
}

第一个操作为&#34;堆栈&#34;上的A类型的对象分配空间,并对其进行默认初始化。可以通过变量a访问此对象。它将在不迟于函数返回时自动销毁和释放;根据周围的上下文,这可能会更早发生,但在变量a范围内的情况下都不会发生。

第二个操作为另一个类型为A对象分配空间,但是在&#34;堆&#34;而不是&#34;堆栈&#34;。此对象也是默认初始化的。 new运算符返回指向此对象的指针,编译器将指针存储在临时变量中。 (我给该变量命名为temp,因为我必须给它一些名称;在原始代码中,临时无法通过任何方式访问。)此对象只有在取消分配时才会被释放。 ,在将来的某个时刻,new返回的指针用于delete操作。

最后,第三个操作将temp指向的堆上的对象的内容复制到堆栈中的对象上,可通过变量{{1}访问}。 (注意:您在此处撰写的a无效,因为static_cast<A>(...)已经有类型*temp。因此,我将其删除了。)

最后,丢弃保存指向堆上对象的指针的临时变量。发生这种情况时,堆上的对象 解除分配;事实上,任何事情都无法解除分配。据说该对象有泄露

你可能想写

A

在堆栈上分配一个对象而不执行任何其他操作,或者

A a;

它在堆上分配一个对象并安排引用计数它,以便它可能不会泄漏。 (你可能还有其他一些意思,但最有可能。)

答案 3 :(得分:1)

对于A的简单定义,它等同于:

A a(*new(A));

在堆上动态分配A,在堆栈上复制构造a,并且泄漏动态分配。

对于A的简单定义,总体效果可能是:

new A;
A a;

此副本实现了泄漏,没有浪费的复制操作或杂乱,冗余的演员:)