gpt4 book ai didi

c++ - 将 new[] 与 delete 配对怎么可能只导致内存泄漏?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:48:47 25 4
gpt4 key购买 nike

首先,根据 C++ 标准,对使用 new[] 分配的任何内容使用 delete 是未定义的行为。

在 Visual C++ 7 中,这种配对会导致两种结果之一。

如果类型 new[]'ed 有简单的构造函数和析构函数 VC++ 简单地使用 new 而不是 new[] 并使用 delete该 block 工作正常 - new 仅调用“分配内存”,delete 仅调用“空闲内存”。

如果类型 new[]'ed 具有非平凡的构造函数或析构函数,则无法完成上述技巧 - VC++7 必须调用正确数量的析构函数。因此它在数组前加上一个 size_t 存储元素的数量。现在 new[] 返回的地址指向第一个元素,而不是 block 的开头。因此,如果使用 delete,它只会调用第一个元素的析构函数,并使用与“分配内存”返回的地址不同的地址调用“空闲内存”,这会导致 HeapFree 内部出现一些错误指示() 我怀疑是指堆损坏。

然而,到处都可以读到错误的陈述,即在 new[] 之后使用 delete 会导致内存泄漏。我怀疑任何大小的堆损坏都比仅为第一个元素调用析构函数并且可能未调用的析构函数没有释放堆分配的子对象这一事实重要得多。

new[] 之后使用 delete 怎么可能只导致某些 C++ 实现上的内存泄漏?

最佳答案

假设我是一个 C++ 编译器,我这样实现我的内存管理:我在每个保留内存块前面加上内存大小(以字节为单位)。像这样的东西;

| size | data ... |
^
pointer returned by new and new[]

请注意,在内存分配方面,newnew[] 没有区别:两者都只是分配一定大小的内存块。

现在 delete[] 如何知道数组的大小,以便调用正确数量的析构函数?只需将内存块的size除以sizeof(T),其中T是数组元素的类型。

现在假设我将 delete 实现为对析构函数的一次简单调用,然后释放 size 字节,那么后续元素的析构函数将永远不会被调用.这会导致后续元素分配的资源泄漏。然而,因为我确实释放了 size 字节(不是 sizeof(T) 字节),所以没有发生堆损坏。

关于c++ - 将 new[] 与 delete 配对怎么可能只导致内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33200992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com