删除导致核心转储,为什么?

delete causes core dumped, and why?

删除新数组而不删除时遇到核心转储[]

这是我的代码:

Page *p;
p = new Page[10];
delete p;

但是当我尝试删除 int[] 时,似乎什么也没有

此处:

int *p;
p = new int[10];
delete p;

我想知道为什么第一个示例导致核心转储,而第二个示例运行完美?

这是我的课程。

class Page {
public:    
    Page() {
        page_id_ = INVALID_PAGE_ID;
        pin_count_ = 0;
        is_dirty_ = 0;
        reset_mem();
    }

    ...
private:
    void reset_mem() { memset(data_, 0, PAGE_SIZE); }

    std::atomic<page_id_t> page_id_;
    std::atomic<int> pin_count_;
    std::atomic<bool> is_dirty_;
    std::atomic<lsn_t> lsn_;

    char data_[PAGE_SIZE];

    ReaderWriterLatch latch_;
};

谢谢!

在分配给 new[] 的指针上使用 delete 而不是 delete[] 会出现未定义的行为。 “似乎有效”是未定义行为的一种可能表现形式; “程序崩溃”是另一个。

实际上,典型实现的行为差异的原因是这样的。对于 class 类型的数组, delete[] 需要对数组的所有元素进行 运行 析构。但是,它只给出了指向第一个元素的指针,而不是大小。为了使其工作,new[] 将分配比数组本身所需更多的内存,在该内存的开头写入数组的大小,并分发超过此长度指示符的指针偏移量。实际上,数组长度存储在返回指针的负偏移处,在数组的第一个元素之前。

delete[] 然后会从负偏移量中读取大小前缀,运行 析构函数,然后向后偏移指针,使其指向已分配内存块的实际开头,并将此传递给调整指向堆管理器的释放例程的指针(例如 free())。

但是当您将此指针传递给普通 delete 时,它不会知道向后调整它,而是会按原样将其传递给 free()(或类似的)。最终结果类似于

char* p = (char*)malloc(256);
free(p + 16);

为什么这是一个问题应该很明显。

对于非class类型的数组,也可能是易破坏的class类型的数组,new[]不分配额外的内存或调整指针,并且delete[] 也不执行任何调整。对于此类类型,delete[] 等同于 delete.