【问题标题】:C++ Heap exception upon deleting an Array of objects删除对象数组时的 C++ 堆异常
【发布时间】:2014-06-28 18:14:48
【问题描述】:

我有这个代码:

class Vards 
{
    public:
    char vards[31];
    //some functions here//
};

Vards *Arr;
Arr = new Vards[word_count];//dynamically allocates 

//do some stuff

delete[] Arr;

一切似乎都很好,但在最后一行 VS 给了我一个例外,并打破了一些奇怪的地方,比如:

extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
        const void * pUserData
        )
{
        if (!pUserData)
            return FALSE;

        if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE))
            return FALSE;

        return HeapValidate( _crtheap, 0, pHdr(pUserData) );
}

然后到

void __cdecl _free_base (void * pBlock)
{

        int retval = 0;


        if (pBlock == NULL)
            return;

        RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));

        retval = HeapFree(_crtheap, 0, pBlock);
        if (retval == 0)
        {
            errno = _get_errno_from_oserr(GetLastError());
        }
}

这应该是正常的吗?我的 CodeBlocks 甚至无法运行该程序(尽管它可以编译它)所以我想知道我是否做错了什么。 我无法搜索任何与此相关的内容。对象数组是否存在某种限制,或者我做错了什么?

[编辑] 根据 Matts 和 barak manos 的建议,我彻底检查了整个代码,发现确实我在访问某个特定位置的索引过大的数组。 可以请你们中的一个发表您的评论作为答案,以便我可以将其标记为已回答吗?

额外问题:如果我在删除之前对堆造成了一些损坏 a) 为什么它没有立即找到它? b)删除后如何找到?

【问题讨论】:

  • 您可能在代码的其他地方有堆损坏(例如,超出了动态分配的缓冲区)。
  • 会不会只发现这一行的堆损坏了?我正在逐行浏览代码,只有在删除时才会抛出异常。
  • 在您的“做一些事情”中,检查以下内容: 1. 您没有尝试访问索引大于word_count-1Arr。 2.您没有尝试访问索引大于30的vards(包括内存复制操作,以及vards中的31个字符都不等于0时的str操作)。
  • 你能提供一个完整的(编译)小例子来重现错误吗?

标签: c++ arrays object exception heap-memory


【解决方案1】:

正如其他人评论的那样,您可能在某处损坏了堆。 (对此发表评论的人应该将其作为答案,以便他们获得荣誉。)

关于你的奖金问题: 当您写入数组的元素(为了速度)时,不会检查索引是否在 C 和 C++ 的范围内。 (当然,如果你试图写入不属于你的内存,你会得到一个分段错误。)

在从 new[] 获得内存之前和之后,分配了几个特殊格式的字节用于簿记。当您使用 delete[] 时,将检查这些字节的有效性以检测损坏的堆。如果我没记错的话,这是否以及如何工作取决于您的平台和编译器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 1970-01-01
    • 2016-04-12
    相关资源
    最近更新 更多