堆栈或堆栈分配不正确
是堆栈或堆场景1中的funcVar?堆栈或堆栈分配不正确
我在问,因为我怀疑它是,因此这可能是一个很好的方法来做事情,以最大限度地减少内存泄漏。也就是说,最好给东西自动分配位置,然后将代码放在堆上的较高级别上,这样可以间接地将事物放在堆上的较低级别,如场景1中所示。
在场景2中,删除可能永远不会被调用。通过使用代码中的场景1,我希望尽量减少(不排除)问题在方案2
方案1
class Test{
int memVar = 1;
void func(){
int funcVar = 2;
SomeClass::someFuncThatCouldCrash();
}
};
Test* t = new Test();
方案2
class Test{
int memVar = 1;
void func(){
int* funcVar = new int(2);
SomeClass::someFuncThatCouldCrash();
delete funcVar; //May not free due to crash in line above;
}
};
Test t; //or Test* t = new Test()
在方案当调用func()
时,1 funcVar
(假设它是int funcVar = 2
)在堆栈上,并且在方案2中它在堆上。你是对的,如果someFuncThatCouldCrash
抛出一个异常,它永远不会被删除。
另外,在场景2中,您删除funcVar
,然后将其返回..这不是好事。同样在那种情况下,当返回类型是一个普通的int时,你返回一个指针。
在C++ 11中,您永远不想处理raw new和delete。基本上,大多数东西都应该是堆栈上的变量。如果您需要堆分配,请使用类似于向量的东西,该向量是堆栈中的本地变量,用于在内部管理堆分配。这样,当矢量离开作用域时,它就可以自行清理而不必调用delete。这就是所谓的RAII(资源分配是初始化),如果你想进一步查看它。如果你确实需要一个指向对象的指针(例如通过基类指针持有一个多态对象,或者通常创建大类的实例),那么你会想要一个std::unique_ptr
本质上创建该局部变量负责在您创建的对象上调用delete
。在较罕见的情况下,您也可能需要std::shared_ptr
,但如果需要,您可以查看所做的事情以及为什么需要它。
嗯......所以在场景1中,memVar将在堆上,但funcVar将在堆栈上,这是正确的吗?我认为,因为memVar在场景1中被间接推送到堆中,那么该函数的“调用堆栈”也会被推送到堆中......但我猜不是。 – code
@code在场景1中,测试't'的实例位于堆上,因此'memvar'(同样需要一个类型)将成为堆上该对象的一部分。当你调用func()时,它会成为调用堆栈中的一个函数,并且它的所有局部变量(包括'funcVar')都是该堆栈帧的一部分。 – RyanP
我明白了。那么你会说如果没有使用std :: unique_ptr或std :: shared_ptr,那么真的没有切换器方法逃避内存泄漏吗? – code
在第一种情况下,它在堆栈上分配。在第二种情况下,它被分配到堆上,并且如果从SomeClass::someFuncThatCouldCrash
中抛出的异常被进一步捕获,则它是正确的。
如果要保持内存安全但使用动态分配,则应根据使用情况使用std::unique_ptr
或std::shared_ptr
。
自动存储中的局部变量位于“堆栈”上。
类成员变量位于“堆栈”或“堆”上,具体取决于类的实例是在“堆栈”还是“堆”上。
全局数据(包括静态局部变量和静态类成员变量)既不在“堆栈”也不在“堆”中。
线程本地数据既不是“堆栈”也不是“堆”(但它可能在堆上实现)。
所以场景1具有funcVar
作为局部变量,因此对“栈”。类Test
的实例在堆上。
在场景2中,funcVar
保留在“堆栈”上,但它指向是“堆”上的内容。它确实不是特例安全的;如果抛出异常,它可能会泄漏。几乎任何操作系统上都会发生崩溃,清理任何“剩余”的简单内存资源。在某些情况下,有时可能会有一些资源在过程退出时不能回收,但它们不是malloc
或new
返回的资源。
使用std::unique_ptr
和std::make_unique
减轻几乎所有的这种泄漏。在现代C++中,避免在类型系统中没有明确拥有的原始指针分配和内存资源通常被认为是一个好主意。
目前尚不清楚此代码的意图。 'funcVar'永远不会被分配给它的值使用,'someFuncThatCouldCrash'不会修改它。 – Xirema
谢谢,iirc和RyanP,我清理了代码以便更清楚。 Xirema,这段代码没有做有用的事情,我保持精简,保持清洁并专注于分配和内存清理。 – code
_is funcVar堆栈或堆场景1?_有人会说它既不是堆栈也不是堆,因为标准没有提到它们中的任何一个。 – skypjack