Проблемы с памятью при работе с двумерным массивом

Следуя этому прекрасному примеру я обнаружил, что пытался создать функцию, которая динамически генерирует 2D-сетку (двумерный массив) из int значений.

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

void testApp::generate2DGrid() {
    int i, j = 0;

    // Delete previous 2D array
    // (happens when previous value for cols and rows is 0)
    if((numRowsPrev != 0) && (numColumnsPrev != 0)) {
        for (i = 0; i < numRowsPrev; i++) {
            delete [ ] Arr2D[i];
        }
    }

    // Create a 2D array
    Arr2D = new int * [numColumns];
    for (i = 0; i < numColumns; i++) {
        Arr2D[i] = new int[numRows];
    }

    // Assign a random values
    for (i=0; i<numRows; i++) {
        for (j = 0; j < numColumns; j++) {
            Arr2D[i][j] = ofRandom(0, 10);
        }
    }

    // Update previous value with new one
    numRowsPrev = numRows;
    numColumnsPrev = numColumns;
}

person ozke    schedule 21.07.2010    source источник


Ответы (2)


2-мерный массив на С++ без проблем с памятью:

#include <vector>

typedef std::vector<int> Array;
typedef std::vector<Array> TwoDArray;

Применение:

TwoDArray Arr2D; 

// Add rows
for (int i = 0; i < numRows; ++i) {
    Arr2D.push_back(Array());
}

// Fill in test data
for (int i = 0; i < numRows; i++) {    
    for (int j = 0; j < numCols; j++) {
        Arr2D[i].push_back(ofRandom(0, 10));           
    }
}

// Make sure the data is there
for (int i = 0; i < numRows; i++) {    
    for (int j = 0; j < numCols; j++) {
        std::cout << Arr2D[i][j] << ' ';
    }
std::cout << '\n';
}
person Vijay Mathew    schedule 21.07.2010
comment
Вы используете C ++, а не C, используйте стандартную библиотеку, которая избавляет вас от проблем, с которыми вы столкнулись в своем вопросе. - person mmmmmm; 21.07.2010
comment
Быстрый комментарий. После // Убедитесь, что данные есть, вы должны заменить 5 на numRows и 10 на numCols - person ozke; 21.07.2010

Я вижу 1 существенную ошибку:

// Assign a random values
for (i=0; i<numRows; i++){
    for (j=0; j<numColumns; j++){
        Arr2D[i][j] = ofRandom(0, 10);
    }
}

Здесь переменная 'i' используется в качестве первого индекса в 'Arr2D' и достигает максимума (numRows -1)
Хотя в этом коде:

for (i=0; i<numColumns; i++)
{
    Arr2D[i] = new int[numRows];
}

Переменная «i» используется в качестве первого индекса, но ее максимальное значение равно (numColumns-1). Если numRows намного больше, чем numColumns, у нас возникнут проблемы.

В качестве примечания. Когда вы пытаетесь очистить, вы пропускаете столбцы:

if((numRowsPrev != 0) && (numColumnsPrev != 0))
{
    for (i=0; i<numRowsPrev; i++){
        delete [ ] Arr2D[i];
    }
    // Need to add this line:
    delete [] Arr2D;
}

Следующее, на что следует обратить внимание.
Это действительно не очень хорошая идея. Используйте некоторые из предоставленных классов STL (или потенциально улучшите Matrix). Похоже, вы привязываете глобальные переменные и всякие другие неприятные вещи.

person Martin York    schedule 21.07.2010
comment
Большое спасибо. Я дам другой ответ как действительный, потому что он выглядит как лучшее решение, но я хотел бы отметить оба, поскольку вы потратили время на поиск проблемы. - person ozke; 21.07.2010