这个内存分配在哪里分配
Where is this memory allocation allocated?
代码行如下:
A a = static_cast<A>(*(new A)); // ?
它至少在64位clang上编译良好。
但是实际分配的内存在哪里,变量a发生了什么?
除了不需要静态强制转换之外,用new A
分配的内存只是泄漏。您已经失去了对该指针的访问权限,并且再也不能正确地delete
它了。
但是实际分配的内存在哪里,变量a发生了什么?
变量a
一旦像往常一样离开作用域就会被销毁。
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.
假设这行代码出现在函数中,我将回答这个问题。如果它出现在其他地方,关于"stack"的部分是不准确的,但其他部分仍然是准确的。
这行代码编译为四个操作,我们可以将它们单独写在c++中,以使事情更清楚。它使两个分配,在两个不同的地方,其中一个被"泄露"。
A a;
{
A *temp = new A;
a = *temp;
}
第一个操作在"堆栈"上为A
类型的对象分配空间,并默认初始化它。这个对象可以通过变量a
访问。它将在函数返回时自动销毁和释放;根据周围的上下文,这可能会更早发生,但在变量a
在作用域中时不会发生。
第二个操作为另一个A
类型的对象分配空间,但是在"堆"而不是"堆栈"上。该对象也是默认初始化的。new
操作符返回指向该对象的指针,编译器将该指针存储在一个临时变量中。(我给这个变量命名为temp
,因为我必须给它一个名字;在原始代码中,无论如何都无法访问临时对象。)只有当new
返回的指针在delete
操作中被使用时,这个对象才会被释放。
temp
指向)复制到堆栈上的对象(通过变量a
可访问)。(注意:您在这里写的static_cast<A>(...)
没有任何影响,因为*temp
已经具有A
类型。因此,我把它拿出来了。
最后,存放堆上对象指针的临时变量被丢弃。当这种情况发生时,堆上的对象而不是被释放;事实上,任何东西都不可能释放它。该对象被称为有泄漏。
你可能想写
A a;
在堆栈上分配对象,不做任何其他操作,或者
// note: C++11 only; C++03 equivalent is std::shared_ptr<A> a(new A());
auto a = std::make_shared<A>();
在堆上分配一个对象,并安排对它进行引用计数,以便它可能不会泄漏。(你可能还有其他一些意思,但这些是最有可能的。)
对于A
的简单定义,它相当于:
A a(*new(A));
A
是在堆上动态分配的,a
是在堆栈上复制构造的,并且动态分配是泄露的。
对于A
的一个简单定义,总体效果可能是:
new A;
A a;
这个副本实现了泄漏,而没有浪费的复制操作或混乱的,冗余的强制转换:)
- C++我需要了解在哪里使用指针和双指针
- 未定义的引用在哪里
- 谷歌测试中的期望值存储在哪里
- 尽管遵循了规则,内存泄漏在哪里
- 堆分配对象中的堆栈对象在 c++ 中在哪里分配?
- 组件对象模型 (COM):IMalloc::Alloc 在哪里分配内存?
- 当我们在C++中创建类的对象时,为成员函数分配的内存在哪里?
- 分配以下对象属性在哪里
- 静态对象的非静态成员分配在哪里
- 我在哪里定义代码来释放在C Python模块init函数中分配的资源
- 类内的成员变量在哪里分配
- ctime 在哪里以及如何分配内存
- 在堆栈上创建对象时分配的内存在哪里
- std::vector 在哪里分配其内存
- 分配后,我必须在哪里释放内存
- 这些参数分配在哪里
- boost::make_shared在哪里为底层对象和引用计数对象分配内存大小
- 模板化的方法代码在哪里分配?
- 这个内存分配在哪里分配
- 在哪里为已初始化的java中的数据成员分配的内存@声明点..