为什么此代码会导致“检测到堆损坏”?

时间:2018-12-28 16:47:30

标签: c++ oop visual-studio-2013

我的代码有问题,我不明白这是怎么回事。

这是代码中出现问题的地方:

void Safe_Array::resize(unsigned new_capacity)
{
    score += sizeof(int)*(new_capacity - m_capacity);

    if (m_capacity < new_capacity)
    {
        int old_len = m_capacity - 1;

        Safe_Array temp(*this);

        if (m_data)
            delete[] m_data;
        m_data = new int[sizeof(int)*new_capacity]; // new allocation
        m_capacity = new_capacity;

        for (int i = 0; i < old_len + 1; i++)
            m_data[i] = temp.m_data[i];

        for (; old_len < new_capacity; old_len++)
            m_data[old_len] = 0;
    }

    else // here we need to shorten the array
    {
        Safe_Array temp(*this);

        if (m_data)
            delete[] m_data;
        m_data = new int[sizeof(int)*new_capacity]; // new allocation
        m_capacity = new_capacity;

        for (int i = 0; i < new_capacity; i++)
            m_data[i] = temp.m_data[i];
    }
}

尝试delete m_data时遇到错误。

此功能的目的:

首先,我创建了一个对象,该对象的m_data是其数组,resize是一个将其“调整大小”该对象字段的函数。

这是标题文件:

class Safe_Array
{
public:
    Safe_Array(unsigned capacity = 0, const int max_tries = 3);
    Safe_Array(const Safe_Array&);
    ~Safe_Array();

    void show(void) const;
    unsigned get_capacity() const;
    bool insert(int, unsigned);
    bool get(unsigned index, int &value) const;
    bool search(int value, unsigned &index) const;
    Safe_Array& assign(const Safe_Array&);
    void resize(unsigned);
    void sort();
    static unsigned get_score();

    friend int compare(const Safe_Array& a, const Safe_Array& b);

    Safe_Array& create(unsigned index1, unsigned index2);

private:
    int *m_data;
    unsigned m_capacity;
    static unsigned score;
    const int m_max_tries;
    unsigned int counter;
};

这是函数的cpp文件。 (包括分页器,承包商,复制承包商和功能调整大小):

Safe_Array::Safe_Array(unsigned capacity, int max_tries) : 
m_max_tries(max_tries), m_capacity(0), m_data(NULL), counter(0)
{
        m_capacity = capacity;
        //counter = 0; // when created counter = 0
        m_data = new int[capacity];
        memset(m_data, 0, m_capacity*sizeof(int));

    score += sizeof(Safe_Array) + sizeof(int)*m_capacity;
}

Safe_Array::Safe_Array(const Safe_Array& org_obj) : 
m_max_tries(org_obj.m_max_tries), m_capacity(org_obj.m_capacity), counter(0) // copy constractor
{
    m_data = new int[m_capacity];
    memcpy(m_data, org_obj.m_data, m_capacity * sizeof(int)); // copy sizeof(int)*4 -> int is 4 bytes & memcpy copies bytes
    score += sizeof(Safe_Array) + sizeof(int)*m_capacity;
}

Safe_Array::~Safe_Array() // distractor
{
    if (m_data) // check if object exists
        delete[] m_data;
    score -= sizeof(Safe_Array) + sizeof(int)*m_capacity; // uptade score
}

1 个答案:

答案 0 :(得分:2)

可能Safe_Array temp(*this);不会(深层)复制m_data,因此在删除之后,您会看到已释放的内存。

稍后删除:

if (m_data) {
  int * old = m_data;

  m_data = new int[sizeof(int)*new_capacity]; // new allocation
  m_capacity = new_capacity;

  for (int i = 0; i < old_len + 1; i++)
     m_data[i] = old[i];

  delete[] old;
}

仅克隆(希望)保存当前实例的成员是一种不好的方法。