【问题标题】:What is a "HEAP CORRUPTION" error in C++?什么是 C++ 中的“堆损坏”错误?
【发布时间】:2019-10-20 12:38:03
【问题描述】:

我在代码上收到“HEAP CORRUPTION DETECTRD: after Normal Block(#72)”错误。这是什么意思?

我不断收到“CRT 检测到应用程序在堆缓冲区结束后写入内存”。 Visual Studio 2019 中的代码出错,它返回 3。但是使用 gcc 编译时相同的代码没有给出错误并返回 0。经过数小时的搜索,我没有找到解决方案。

#include <iostream>

    class Vector
    {
    public:
        Vector();
       ~Vector();
        std::size_t size() const { return m_end - m_begin; }
        std::size_t capacity() const { return m_capacity - m_begin; }
        int* begin() const { return m_begin; }
        int* end() const { return m_end; }
        void push_back(const int& );
        Vector(const Vector& obj)
    {
        int* rhs_beg = obj.m_begin;
        int* new_beg = alloc.allocate(size());
        int* temp_new_beg = new_beg;
        for (std::size_t it = 0; it != size(); ++it)
        {
            alloc.construct(temp_new_beg++, *rhs_beg++);
        }
        m_begin = new_beg;
        m_capacity = m_end = temp_new_beg;
    }


    private:
      std::allocator<int> alloc;
      int* m_begin, *m_end, *m_capacity;
          void chk_n_alloc();
      void allocate();
      void free();
};

    Vector::Vector()
    :m_begin(nullptr), m_end(nullptr), m_capacity(nullptr)
    {
    }

    void Vector::free()
    {
       for (auto it = m_end; it != m_begin;)
        alloc.destroy(--it);
       alloc.deallocate(m_begin, size());
    }

    void Vector::chk_n_alloc()
    { 
       if (size() == capacity())
        allocate();
    }

    void Vector::allocate()
    {
       std::size_t n_size;
       int* beg = nullptr;
       if (!size())
        beg = alloc.allocate(1);
       else
                beg = alloc.allocate(size() * 2);
       int* new_begin = beg;
       int* t_begin = m_begin;
       for (int i = 0; i != size(); ++i)
                alloc.construct(new_begin++, std::move(*t_begin++));
       free();
       m_begin = beg;
       m_end = new_begin;
       n_size = size() * 2;
       m_capacity = m_begin + n_size;
    }

      void Vector::push_back(const int& x)
    {
        chk_n_alloc();
        alloc.construct(m_end++, x);
    }

    Vector::~Vector()
    {
        free();
    }

    int main()
    {
       Vector v;

       v.push_back(12);
       v.push_back(10);

    }

只有当我尝试多次调用 Vector::push_back() 时才会发生错误。这里是错误代码:“HEAP CORRUPTION DETECTRD: after Normal Block(#72)。”

【问题讨论】:

  • 嗨。这不是您遇到堆问题的直接原因,但您可能需要重新考虑使用 size()capacity() 的指针。您实际上是在减去指针的地址,而不是整数值。
  • 使用 clang++ 8.0.0 编译时的 valgrind 结果:pastebin.com/wc7Dhw01 使用 g++ 9.2.1 编译时没有发现错误。
  • 使用 gcc 和 valgrind 它指向我的电脑上的错误... ==8330== 大小为 4 的无效写入 ==8330== 在 0x401696: void __gnu_cxx::new_allocator: :construct(int*, int const&) (new_allocator.h:136)
  • for (int i = 0; i != size();) 这个循环应该如何结束?当您将元素从旧内存复制到新内存时,它会创建一个无限循环。因此,您最终会覆盖不属于您的内存。
  • 循环在源代码中有一个增量。但不知何故,我可能在帖子中意外删除了它。即使增量也会出现同样的错误。我将编辑帖子以添加它。跨度>

标签: c++


【解决方案1】:

这意味着你的程序正在写入它不应该写入的内存,并覆盖了运行时用来管理堆的管理内存。

常见原因有:

  • 在分配的块之外写入。例如。 new[] 大小为 4 的数组,并写入第 5 或第 6(等)项。负偏移也可以这样。
  • 释放内存并在之后写入。
  • 取消引用(并写入)指向随机内存位置的未初始化指针

在您的代码中,我会仔细检查您访问的内存、访问时间以及当时这样做是否安全。您可以使用调试器来跟踪您的代码正在执行的操作,或者使用地址清理程序构建/运行,这会提供有关此类错误的更有意义的信息。

【讨论】:

  • ... 因为它是 heap 损坏,被覆盖的内存是用 new、malloc 或其他基于堆的分配保留的,所以它不是例如普通的堆栈绑定数组。
猜你喜欢
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-03
  • 2013-09-29
  • 1970-01-01
  • 2011-12-03
  • 2011-08-03
相关资源
最近更新 更多