我正在使用DevStudio在Windows上开发,在C / C ++中不受管理。
我想在堆栈而不是堆上分配一些内存,因为我不想处理手动释放内存(我知道智能指针和所有这些东西。我有一个非常特殊的内存情况分配我需要处理),类似于使用A2W()和W2A()宏。
_alloca 会这样做,但已弃用。建议使用 malloca 。但_malloca文档说,每次调用_malloca都必须调用___ freea 。然后它失败了我使用_malloca的目的,我将使用malloc或new。
有人知道我是否可以在没有泄漏的情况下忘记调用_freea以及内部的影响是什么?
否则,我最终只会使用弃用的_alloca函数。
答案 0 :(得分:13)
每次调用_malloca后调用_freea都很重要。
_malloca就像_alloca,但为您的保护添加了一些额外的安全检查和增强功能。因此,_malloca可以在堆上而不是堆栈上进行分配。如果发生这种情况,并且您没有调用_freea,则会出现内存泄漏。
在调试模式下,_malloca总是在堆上分配,所以也应该被释放。
搜索_ALLOCA_S_THRESHOLD以获取有关阈值如何工作的详细信息,以及为什么存在_malloca而不是_alloca,这应该是有意义的。
编辑:
有评论表明这个人只是在堆上分配,并使用智能指针等。
堆叠分配有很多优点,_malloca将为您提供,因此有理由希望这样做。 _alloca将以相同的方式工作,但更有可能导致堆栈溢出或其他问题,并且遗憾的是不提供好的异常,而是倾向于拆除您的进程。 _malloca在这方面更加安全,并且可以保护你,但是成本是你仍然需要用_freea释放你的记忆,因为_malloca会选择在堆而不是堆栈上分配,因为它可能(但在发布模式下不太可能)。
如果您的唯一目标是避免释放内存,我建议您使用智能指针,以便在成员超出范围时为您释放内存。这将在堆上分配内存,但是安全,并防止您必须释放内存。这只适用于C ++ - 如果你使用普通的'C',这种方法将不起作用。
如果你因为其他原因(通常是性能,因为堆栈分配非常非常快)而尝试在堆栈上进行分配,我建议使用_malloca并且生活在你需要为你的值调用_freea的事实上
答案 1 :(得分:3)
要考虑的另一件事是使用RAII类来管理分配 - 当然,只有在您的宏(或其他)可以限制为C ++时才有用。
如果您出于性能原因想避免碰到堆,请查看Matthew Wilson的auto_buffer<>
模板类(http://www.stlsoft.org/doc-1.9/classstlsoft_1_1auto__buffer.html
)使用的技术。这将在堆栈上进行分配,除非您的运行时大小请求超过编译器时指定的大小 - 因此您可以获得大多数分配的无堆分配速度(如果您正确调整模板大小),但是如果超出大小,一切仍然可以正常工作那个大小。
由于STLsoft在处理可移植性问题方面有很多不足之处,您可能需要查看Wilson书中"Imperfect C++".
中描述的更简单的auto_buffer<>
版本。
我发现它在嵌入式项目中非常方便。
答案 2 :(得分:1)
要在堆栈上分配内存,只需声明一个适当类型和大小的变量。
答案 3 :(得分:1)
之前我回答过这个问题,但是我错过了一些基本的东西,这意味着它只能在调试模式下工作。我将调用_malloca转移到了一个可以自动释放的类的构造函数中。
在调试中这很好,因为它总是在堆上分配。但是,在发布时,它会在堆栈上分配,从构造函数返回后,堆栈指针已被重置,内存丢失。
我回过头来采取了不同的方法,结果是使用宏(eurgh)来分配内存并实例化一个自动在该内存上调用_freea的对象。由于它是一个宏,它被分配在相同的堆栈帧中,因此实际上将在发布模式下工作。它和我的班级一样方便,但使用起来不太好。
我做了以下事情:
class EXPORT_LIB_CLASS CAutoMallocAFree
{
public:
CAutoMallocAFree( void *pMem ) : m_pMem( pMem ) {}
~CAutoMallocAFree() { _freea( m_pMem ); }
private:
void *m_pMem;
CAutoMallocAFree();
CAutoMallocAFree( const CAutoMallocAFree &rhs );
CAutoMallocAFree &operator=( const CAutoMallocAFree &rhs );
};
#define AUTO_MALLOCA( Var, Type, Length ) \
Type* Var = (Type *)( _malloca( ( Length ) * sizeof ( Type ) ) ); \
CAutoMallocAFree __MALLOCA_##Var( (void *) Var );
这样我可以使用下面的宏调用进行分配,并在实例化的类超出范围时释放它:
AUTO_MALLOCA( pBuffer, BYTE, Len );
Ar.LoadRaw( pBuffer, Len );
我很抱歉发布了一些明显错误的内容!
答案 4 :(得分:0)
如果您不得不释放临时内存,而且您知道智能指针之类的内容,那么为什么不使用类似的模式,当内存超出范围时会释放内存?
template <class T>
class TempMem
{
TempMem(size_t size)
{
mAddress = new T[size];
}
~TempMem
{
delete [] mAddress;
}
T* mAddress;
}
void foo( void )
{
TempMem<int> buffer(1024);
// alternatively you could override the T* operator..
some_memory_stuff(buffer.mAddress);
// temp-mem auto-freed
}
答案 5 :(得分:0)
如果您正在使用_malloca()
,则必须调用_freea()
以防止内存泄漏,因为_malloca()
可以在堆栈或堆上进行分配。如果给定大小超过_ALLOCA_S_THRESHOLD值,它将在堆上进行分配。因此,如果分配发生在堆栈上,则调用_freea()
更安全,后者不会做任何事情。
如果您使用的_alloca()
似乎已于今天被弃用;由于分配发生在堆栈上,因此无需调用_freea()
。