Почему этот код приводит к «обнаружению повреждения кучи»? - PullRequest
0 голосов
/ 28 декабря 2018

У меня проблема с моим кодом, и я не понимаю, что с ним не так.

Вот где проблема возникает в коде:

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];
    }
}

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 голосов
/ 28 декабря 2018

вероятно 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;
}

Для клонированиятекущий экземпляр просто (надеюсь) сохранить его член - плохой способ.

...