我正在用DevStudio在Windows上开发,在C / C ++非托pipe。
我想分配一些内存堆栈而不是堆,因为我不想处理手动释放内存(我知道智能指针和所有这些东西。我有一个非常具体的内存分配的情况下,我需要处理),类似于使用A2W()和W2A()macros。
_alloca是这样做的,但是已经被弃用了。 build议使用malloca来代替。 但_malloca文档说,___freea的调用是_malloca的每次调用必需的。 然后它打败了我使用_malloca的目的,我将使用malloc或new。
任何人都知道,如果我不能在没有泄漏的情况下调用_freea,以及内部的影响是什么?
否则,我最终只会使用已弃用的_alloca函数。
每次调用_malloca之后调用_freea总是很重要的。
_malloca就像_alloca,但增加了一些额外的安全检查和增强您的保护。 因此,_malloca可能在堆上而不是堆栈上进行分配。 如果发生这种情况,并且不调用_freea,则会发生内存泄漏。
在调试模式下,_malloca总是分配在堆上,所以也应该被释放。
搜索_ALLOCA_S_THRESHOLD以获取阈值如何工作的细节,以及_malloca为什么存在而不是_alloca,这应该是有道理的。
编辑:
有人建议,这个人只是在堆上分配,并使用智能指针等。
堆栈分配有好处,_malloca会提供给你,所以有理由要这样做。 _alloca将以相同的方式工作,但更有可能导致堆栈溢出或其他问题,不幸的是不提供很好的例外,而是往往只是推翻你的过程。 _malloca在这方面比较安全,并且保护你,但是代价是你仍然需要用_freea释放你的内存,因为_malloca可能选择在堆上而不是栈上分配。
如果你唯一的目标是避免释放内存,我会建议使用一个智能指针,当成员超出范围时,将为你释放内存。 这将在堆上分配内存,但要安全,并且不要释放内存。 这只会在C ++中起作用 – 如果你使用的是普通的C语言,这种方法是行不通的。
如果你试图在堆栈上分配其他原因(通常是性能,因为堆栈分配是非常非常快的),所以我建议使用_malloca,并且事实上你需要在你的值上调用_freea。
另外要考虑的是使用RAII类来管理分配 – 当然这只有在你的宏(或其他)可以被限制到C ++时才有用。
如果您想避免因性能原因而碰到堆,请查看Matthew Wilson的auto_buffer<>
模板类( http://www.stlsoft.org/doc-1.9/classstlsoft_1_1auto__buffer.html
)所使用的技术。 这将在堆栈上分配,除非您的运行时间大小请求超过编译器时间指定的大小 – 所以您可以获得大部分分配(如果您调整模板的大小)没有堆分配的速度,但是如果超出那大小。
由于STLsoft在处理可移植性问题上有很多难题,所以您可能需要查看一下在Wilson的书“Imperfect C ++”中描述的更简单的auto_buffer<>
版本。
我发现它在嵌入式项目中非常方便。
要在堆栈中分配内存,只需声明适当类型和大小的变量即可。
我之前回答了这个问题,但是我错过了一些基本的东西,这意味着它只能在调试模式下工作。 我把调用_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 );
我很抱歉发布一些明显错误的东西!
如果你的问题是不得不释放临时内存,并且你知道所有关于智能指针的事情,那么为什么不使用类似的模式,当内存在超出范围时被释放?
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 }
如果使用_malloca()
则必须调用_freea()
来防止内存泄漏,因为_malloca()
可以在堆栈或堆上执行分配。 如果给定的大小超过_ALLOCA_S_THRESHOLD值,它将在堆上进行分配。 因此,调用_freea()
如果分配发生在栈上将不会执行任何操作。
如果您使用_alloca()
,似乎今天已经废弃; 没有必要调用_freea()
作为分配发生在堆栈上。