Копирование динамически размещенного массива в больший массив без утечки памяти

Я пытаюсь увеличить размер двух моих динамически выделяемых массивов указателей на единицу, поэтому я создаю временные массивы, копирую свои старые значения, удаляю оригиналы и затем переназначаю их. Код компилируется и работает нормально, но я получаю утечку памяти и не могу понять это.

Моими переменными-членами являются ширина, * высота и ** данные.

void Tetris::add_right_column() {

    width += 1;
    int* temp_heights = new int[width];
    char** temp_data = new char*[width];

    // copies old values into the temp one
    for (int i=0; i<width-1; i++) {
        temp_heights[i] = heights[i];
        temp_data[i] = data[i];
    }

    // adds new value into temps
    temp_data[width-1] = new char[0];
    temp_heights[width-1] = 0;

    // deletes original arrays of pointers
    delete [] heights;
    delete [] data;

    // reassigns the pointers
    heights = temp_heights;
    data = temp_data;

}

Я использую Dr.Memory и у меня есть некоторые утечки:

Error #2: LEAK 28 direct bytes 0x019685c0-0x019685dc + 0 indirect bytes
# 0 replace_operator_new_array               [d:\drmemory_package\common\alloc_replace.c:2928]
# 1 Tetris::add_right_column                 [********/tetris.cpp:308]
# 2 additional_student_tests                 [********/main.cpp:276]
# 3 main                                     [********/main.cpp:41]

Error #3: LEAK 28 direct bytes 0x01968600-0x0196861c + 12 indirect bytes
# 0 replace_operator_new_array               [d:\drmemory_package\common\alloc_replace.c:2928]
# 1 Tetris::add_right_column                 [********/tetris.cpp:309]
# 2 additional_student_tests                 [********/main.cpp:276]
# 3 main                                     [********/main.cpp:41]

Все, что я знаю, это то, что память, которую я выделяю в этих двух строках:

int* temp_heights = new int[width];
char** temp_data = new char*[width];

не освобождается должным образом. Я пробовал:

delete [] temp_heights;
delete [] temp_data;

и

// after copying data[i] over to temp_data[i]
for (int i=0; i<width; i++) {
    delete data[i];
}

но оба из них заставляют его перестать работать. Я знаю, что не могу использовать перераспределение, потому что я использую новый. Как мне лучше всего избежать утечки памяти в этом случае?

РЕДАКТИРОВАТЬ:

Мой конструктор:

Tetris::Tetris(int given_width) {
    width = given_width;
    heights = new int[width]; 
    // sets n (width) number of heights = to 0
    for (int i =0; i<width; i++) {
        heights[i] = 0;
    }
    // same type as the type of the arrays it points to
    data = new char*[width];
    for (int i=0; i<width; i++) {
        data[i] = new char[heights[i]];
    }
}

Мой деструктор:

void Tetris::destroy() {
    delete [] data;
    delete [] heights;
 }

Мои занятия:

class Tetris {
public:

    // CONSTRUCTORS
    Tetris(int given_width);

    // ACCESSORS
    int get_width() const { return width;};
    int get_max_height() const;
    int count_squares() const;
    void print() const;
    void destroy();
    int count_squares();

    // MODIFIERS
    void add_piece(char piece, int rotation, int position);
    int remove_full_rows();
    void add_left_column() { };
    void add_right_column();
    void remove_right_column() { };
    void remove_left_column() { };

private:
    // MEMBER VARIABLES
    int width;
    int *heights;
    char **data;
};

Пример основного:

void main() {
    Tetris tetris(6);
    tetris.print();
    tetris.add_right_column();
    tetris.print();
}

person Sunden    schedule 19.02.2016    source источник
comment
Копирование динамически размещенного массива в массив большего размера без утечки памяти — Просто — используйте std::vector — для этого он и был разработан.   -  person PaulMcKenzie    schedule 20.02.2016
comment
Это домашнее задание, и мне не разрешено использовать векторы, по крайней мере, я бы определенно разрешил.   -  person Sunden    schedule 20.02.2016
comment
Ну, вы думали о том, чтобы просто создать класс динамического массива, а затем использовать его вместо одноразовых вещей, подобных этому? Гораздо лучше создать рабочий класс динамического массива, а затем использовать его в будущих заданиях.   -  person PaulMcKenzie    schedule 20.02.2016
comment
как выглядит деструктор? add_right_column() выглядит правильно.   -  person Vishal Kumar    schedule 20.02.2016
comment
@Sunden Есть ли в вашем классе Tetris соответствующий определяемый пользователем конструктор копирования, оператор присваивания и деструктор? Если копии объектов Tetris сделаны, а этих функций у вас нет (или они глючат), то программа будет демонстрировать неопределённое поведение.   -  person PaulMcKenzie    schedule 20.02.2016
comment
Также было бы полезно, если бы вы разместили тестовую программу, а не только код, который сам по себе не вызывает проблем. Это код, который вы нам не показываете (или код, который вы не писали, например, конструктор копирования, оператор присваивания и деструктор), который вызывает проблему.   -  person PaulMcKenzie    schedule 20.02.2016
comment
Этот код кажется мне правильным. Единственное, что, как я предполагаю, вам не хватает, это деструктор, вам нужно будет удалить все элементы данных [], прежде чем вы удалите сам массив данных. Хотя без всего кода это дикая догадка   -  person Signal Eleven    schedule 20.02.2016
comment
Прошу прощения, я разместил остальную часть моего кода выше.   -  person Sunden    schedule 20.02.2016
comment
В вашем классе нет деструктора. Деструктор — это не функция с именем destroy. Где ~Tetris{}?   -  person PaulMcKenzie    schedule 20.02.2016
comment
Кроме того, если вы посмотрите на то, как вы создаете Tetris, вы делаете 3 вызова new[ ] (если вы не считаете циклы). Поэтому вы должны сделать 3 вызова delete[ ], а не только 2 вызова при освобождении памяти.   -  person PaulMcKenzie    schedule 20.02.2016
comment
Спасибо, я попытался удалить все данные [w], которые я назначил в конструкторе, и устранил утечку. Я посмотрю на деструкторы.   -  person Sunden    schedule 20.02.2016


Ответы (1)


Ваши данные [] содержат массив char *, который вы каждый раз выделяете в куче.

Прежде чем удалять [] данные, убедитесь, что вы удалили все «новые символы», на которые указывает ваш массив данных.

person Sam Daniel    schedule 19.02.2016