微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决删除导致核心转储,为什么?

在不使用 delete[] 的情况下删除数组 new 时遇到 core dump

这是我的代码

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_,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_;
};

谢谢!

解决方法

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

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

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

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

free()

这是一个问题的原因应该很明显。

对于非类类型的数组,也许还有一个普通可破坏的类类型,char* p = (char*)malloc(256); free(p + 16); 不会分配额外的内存或调整指针,new[] 不会执行任何调整任何一个。对于此类类型,delete[] 等效于 delete[]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。