我有这个代码:
class Vards
{
public:
char vards[31];
//some functions here//
};
Vards *Arr;
Arr = new Vards[word_count];//dynamically allocates
//do some stuff
delete[] Arr;
一切似乎都很好,但在最后一行 VS 给了我一个异常(exception)并中断到一些奇怪的地方,例如:
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)删除后如何找到它?
最佳答案
正如其他人评论的那样,您可能在某处破坏了堆。 (对此发表评论的人应该将其作为答案,这样他们才能获得荣誉。)
关于您的奖励问题: 当您写入数组的元素(为了速度)时,不会检查索引是否在 C 和 C++ 中的范围内。 (当然,如果你试图写入不属于你的内存,你会得到一个段错误。)
在你从 new[] 获得的内存之前和之后,分配了几个特殊格式的字节用于记账。当您使用 delete[] 时,将检查这些字节的有效性以检测损坏的堆。如果我没记错的话,这是否以及如何工作取决于您的平台和编译器。
关于删除对象数组时出现 C++ 堆异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23591153/