【问题标题】:Stack overflow due to heap allocation/deallocation由于堆分配/释放导致的堆栈溢出
【发布时间】:2009-09-14 01:54:21
【问题描述】:

编辑:为了清楚起见,这个问题是由我的代码中的拼写错误引起的, 在

pointer = new BYTE(datasize);

应该是

pointer = new BYTE[datasize];

一切都好!

结束

嗨!

我在 C++ 项目中的 Visual Studio 2005 中遇到了奇怪的堆栈溢出问题..

在我的代码中,我有一个

BYTE* pointer;

这个指针被设置为NULL,然后分配了一些内存,然后清除为0x00。像这样:

pointer = NULL;
pointer = new BYTE(dataSize);
memset(pointer,0x00,dataSize);

现在,我已经运行了几次,得到了两个不同的结果。有时(在程序的后面部分,当我用 delete[] 删除指针时)它说堆已损坏,并且在检查调用堆栈时,似乎 _CrtIsValidHeapPointer 断言它不是一个有效的指针。但是我检查了这个指针,它对我来说似乎是有效的(它有一个内存地址)。我错过了什么吗?

在另一种情况下,应用程序冻结了很短的时间,并且我收到了堆栈溢出消息。当我检查调用堆栈时,它看起来像这样

 something.dll!_heap_alloc_base(unsigned int size=568)  Line 105 + 0x28 bytes   C
something.dll!_heap_alloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 411 + 0x9 bytes C++
something.dll!_nh_malloc_dbg(unsigned int nSize=532, int nhFlag=0, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 268 + 0x15 bytes   C++
something.dll!_malloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 191 + 0x1b bytes    C++
something.dll!_calloc_dbg(unsigned int nNum=1, unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 563 + 0x15 bytes   C++
something.dll!_getptd_noexit()  Line 608 + 0x18 bytes   C
something.dll!_errno()  Line 281 + 0x5 bytes    C
something.dll!_heap_alloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 415 + 0x5 bytes C++
something.dll!_nh_malloc_dbg(unsigned int nSize=532, int nhFlag=0, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 268 + 0x15 bytes   C++
something.dll!_malloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 191 + 0x1b bytes    C++
something.dll!_calloc_dbg(unsigned int nNum=1, unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 563 + 0x15 bytes   C++
something.dll!_getptd_noexit()  Line 608 + 0x18 bytes   C
something.dll!_errno()  Line 281 + 0x5 bytes    C
something.dll!_heap_alloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 415 + 0x5 bytes C++
something.dll!_nh_malloc_dbg(unsigned int nSize=532, int nhFlag=0, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 268 + 0x15 bytes   C++
something.dll!_malloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 191 + 0x1b bytes    C++
something.dll!_calloc_dbg(unsigned int nNum=1, unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 563 + 0x15 bytes   C++
something.dll!_getptd_noexit()  Line 608 + 0x18 bytes   C
something.dll!_errno()  Line 281 + 0x5 bytes    C
something.dll!_heap_alloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 415 + 0x5 bytes C++
something.dll!_nh_malloc_dbg(unsigned int nSize=532, int nhFlag=0, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 268 + 0x15 bytes   C++
something.dll!_malloc_dbg(unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 191 + 0x1b bytes    C++
something.dll!_calloc_dbg(unsigned int nNum=1, unsigned int nSize=532, int nBlockUse=2, const char * szFileName=0x0627fec8, int nLine=608)  Line 563 + 0x15 bytes   C++
something.dll!_getptd_noexit()  Line 608 + 0x18 bytes   C
something.dll!_errno()  Line 281 + 0x5 bytes    C

有很多这样的调用,我很确定这会导致堆栈溢出。知道这个问题可能是什么吗?我尝试查看是否分配/释放错误,但我没有写入除 memset 之外分配的内存块..

我分配/释放内存的方式有问题吗?

我正在使用此代码来解除分配:

if (pointer != NULL){
    delete[] pointer;
    pointer = NULL;
}

这应该确保我没有释放已经释放的内存对吗?

谢谢..

编辑:在输出窗口中,我还得到了很多:

First-chance exception at 0x76df0839 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e2871f in app.exe: 0xC0000005: Access violation reading location 0x00000004.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.
First-chance exception at 0x76e00a65 in app.exe: 0xC0000005: Access violation reading location 0xfffffff8.

【问题讨论】:

    标签: c++ visual-studio-2005 memory-management stack-overflow


    【解决方案1】:

    我想你的意思是:

    pointer = new BYTE[size];
    

    【讨论】:

    • 哦,我明白了,new byte(size)new byte[size] 将分配相同数量的内存,但您拥有delete 前者和delete [] 后者。
    • @Igor: 不正确的new byte(size) 将分配一个字节并使用值size 对其进行初始化。 new byte[size] 将创建 size 字节,没有默认初始化。
    【解决方案2】:

    您的取消分配代码应为:

    if (pointer != NULL){
        delete[] pointer;
        pointer = NULL;
    }
    

    【讨论】:

    • 不,NULL 测试是不必要的。
    • 是的,我只是在回复 OP 中的错字:))
    • 是的。该标准规定尝试删除null 与什么都不做一样。
    猜你喜欢
    • 2019-12-21
    • 2015-05-21
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多