用于调试和发布的heapalloc()函数有什么区别? [英] What is the difference between heapalloc() function for debug and release ?

查看:112
本文介绍了用于调试和发布的heapalloc()函数有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目使用两个不同的功能进行发布和调试。我的代码在发布版本中崩溃,同时分配内存。



发布:

 WINBASEAPI 
_Ret_maybenull_
_Post_writable_byte_size_(dwBytes)
LPVOID
WINAPI
HeapAlloc(_In_ HANDLE hHeap,_In_ DWORD dwFlags,_In_ SIZE_T dwBytes);





调试:

 #ifdef _DEBUG 
#define HeapAlloc(a,b,c)_calloc_dbg((c), 1,_NORMAL_BLOCK,__ FILE __,_ _ _ _ _ _ _ _ _ _ _ _ _ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
代码如下所示,它用于C ++ \ VCC ++中的READ xml文件。

在这里,我只写了样本部分,它将逐行读取。



 HANDLE hHeap = NULL ; 
SYSTEM_INFO si;
GetSystemInfo(& si);
hHeap = HeapCreate(HGE,16 * si.dwPageSize,0L);

int HGE = HEAP_GENERATE_EXCEPTIONS;
TCHAR * xmlTag = _T(nXMLPages);
size_t lenTag = _tcslen(xmlTag);
TCHAR * StartXMLTag = NULL,* EndXMLTag = NULL;
StartXMLTag =(TCHAR *)HeapAlloc(hHeap,HGE,(lenTag + 2)* sizeof(TCHAR));
EndXMLTag =(TCHAR *)HeapAlloc(hHeap,HGE,(lenTag + 4)* sizeof(TCHAR));



//为EndXMLTag调用HeapAlloc()时出现崩溃



我尝试过:



输入文件数据如下; < nxmlpages> 4

解决方案

发布版本中的典型故障是由于未初始化的变量而发生的。无论如何,在你提供的示例代码中,变量被初始化 HGE 除外,它甚至在声明之前使用 i>,相信编译器会抱怨)。我看到你没有检查 HeapCreate 的返回值。


不同之处在于调试模式它调用了内存跟踪版本calloc和在发布中它调用HeapAlloc。这两者差别很大,需要不同的相应释放功能。此外,使用malloc / calloc系列不需要首先像HeapAlloc那样创建堆。以下是微软对它们的评价:比较内存分配方法Microsoft Docs [ ^ ]



就个人而言,除非我不得不继续使用malloc系列调用(新的/删除c ++)所以我可以采取他们可以使用的内存跟踪功能的优点。



如果你必须使用HeapAlloc,这是一个方便的小模板类,可以帮助你。好处是它在删除对象时自动释放内存,并提供不需要转换指针的操作符。它使用全局堆,因此您不必创建一个。无论如何,这里是:

  template < typename T>  class  CHeapAlloc 
{
public
CHeapAlloc( size_t count = 1
{
size_t size = count * sizeof (T);
m_ptr =(T *):: HeapAlloc(:: GetProcessHeap(),HEAP_ZERO_MEMORY,size);
}

虚拟 ~CHeapAlloc()
{
if (m_ptr)
{
:: HeapFree(:: GetProcessHeap(), 0 ,m_ptr);
m_ptr = nullptr ;
}
}

运算符 T *(){ return m_ptr; }

T * operator - >(){ return m_ptr; }

public
T * m_ptr;
};

我不记得我发现了什么,但我认为它来自这里。


My project use two different function for release and debug. My code is crashing in release version, while allocation of memory.

Release:

WINBASEAPI
_Ret_maybenull_
_Post_writable_byte_size_(dwBytes)
LPVOID
WINAPI
HeapAlloc(_In_ HANDLE hHeap,_In_ DWORD dwFlags,_In_ SIZE_T dwBytes);



Debug:

#ifdef _DEBUG
#define HeapAlloc( a, b, c ) _calloc_dbg( (c), 1, _NORMAL_BLOCK, __FILE__, __LINE__ )
#endif





Code is as per below, it's used for READ xml file in C++\VC++.
Here, I wrote only sample part, which will be read line by line.

HANDLE hHeap = NULL;
SYSTEM_INFO si;
GetSystemInfo( &si );
hHeap = HeapCreate( HGE, 16 * si.dwPageSize, 0L );

int HGE = HEAP_GENERATE_EXCEPTIONS;
TCHAR *xmlTag = _T("nXMLPages");
size_t lenTag = _tcslen( xmlTag );
TCHAR *StartXMLTag = NULL, *EndXMLTag = NULL;
StartXMLTag = (TCHAR *) HeapAlloc( hHeap, HGE, ( lenTag + 2 ) * sizeof( TCHAR ) );
EndXMLTag = (TCHAR *) HeapAlloc( hHeap, HGE, ( lenTag + 4 ) * sizeof( TCHAR ) );	


//Crashing place while call HeapAlloc() for EndXMLTag

What I have tried:

Input file data is like; <nxmlpages>4

解决方案

Typical failures in release version happen due to uninitialised variables. Anyway, in the sample code you provided, variables are initialised (with the exception of HGE which is used even before its declaration, a believe the compiler would complain about). I see you didn't check the return value of HeapCreate.


The difference is in debug mode it calls the memory tracking version of calloc and in release it calls HeapAlloc. These two are vastly different and require different, corresponding release functions. Also, using the malloc/calloc family does not require you to create a heap first as HeapAlloc does. Here's what microsoft has to say about them : Comparing Memory Allocation Methods | Microsoft Docs[^]

Personally, unless I had to I would stay with the malloc family of calls (new/delete for c++) so I could take advantage of the memory tracking functionality that is available with them.

If you MUST use HeapAlloc here is a handy little template class that can help you with it. The nice thing is it automatically releases the memory when the object is deleted and provides operators that remove the need for casting of the pointer. It uses the global heap so you don't have to create one. Anyway, here it is:

template <typename T> class CHeapAlloc
{
public:
    CHeapAlloc( size_t count = 1 )
    {
        size_t size = count * sizeof( T );
        m_ptr = (T *)::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, size );
    }

    virtual ~CHeapAlloc()
    {
        if( m_ptr )
        {
            ::HeapFree( ::GetProcessHeap(), 0, m_ptr );
            m_ptr = nullptr;
        }
    }

    operator T*()         { return m_ptr; }

    T * operator->()      { return m_ptr; }

public:
    T * m_ptr;
};

I can't remember where I found this but I think it came from here.


这篇关于用于调试和发布的heapalloc()函数有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆