Проблемы при динамическом размещении матрицы в памяти - PullRequest
0 голосов
/ 13 мая 2019

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

По сути, каждый раз, когда моя программа запускается, она выделяет матрицу, размер которой генерируется случайным образом на лету.

coord mapSize;

mapSize.row = randomRange(3, 5);
mapSize.column = randomRange(5, 7);

char** map = (char**) malloc (mapSize.row * sizeof(char));

for (int i = 0; i < mapSize.row; i++) 
{
    map[i] = (char*) malloc (mapSize.column * sizeof(char));
}

Тогда матрица инициализируется:

for (int i = 0; i < mapSize.row; i++)
{
    for (int j = 0; j < mapSize.column; j++)
    {
        map[i][j] = CLEAN_FLOOR_SYMBOL;
    }
}

Это прекрасно работает, если размер матрицы не превышает 4 строки. Если это происходит, программа просто падает, когда инициализация попадает в пятую строку. Что еще более странно, так это то, что даже если число строк превышает 5, проблема все еще возникает, когда инициализация достигает пятой строки.

Я подтвердил это, распечатав некоторые значения во время циклов инициализации.

printf("r: %d c: %d\n\n", mapSize.row, mapSize.column);

for (int i = 0; i < mapSize.row; i++)
{
    printf("r: %d | c: ", i);
    for (int j = 0; j < mapSize.column; j++)
    {
        map[i][j] = CLEAN_FLOOR_SYMBOL;
        printf("%d ", j);
    }
    printf("\n");
}

error

Здесь было 6 строк, но программа все еще не работала при попытке инициализировать пятую.

Что еще более странно, так это то, что ни одна из этих проблем не возникает при запуске программы на консоли eclipse. Итак, как и я все испортил?

1 Ответ

2 голосов
/ 13 мая 2019

В

char** map = (char**) malloc (mapSize.row * sizeof(char));

вам не хватает *, и, пожалуйста, не разыгрывайте результат *alloc()*) :

char **map = malloc (mapSize.row * sizeof(char*));
//                                            ^
//                                           here

Лучше:

char **map = malloc (mapSize.row * sizeof(*map));

так как здесь тип определяется размером изменений с типом map, поэтому вам не нужно помнить об изменении типа в нескольких местах, если он когда-либо изменится.

Если вам нужна производительность, избавьтесь от **. Посмотрите, что такое зубчатый массив, и избегайте его:

size_t num_rows = // ...
size_t num_cols = // ...
char *foo = malloc(num_rows * num_cols * sizeof *foo);

// access:
size_t row = // ...
size_t col = // ...
foo[row * num_rows + col];


*) Если ваш компилятор жалуется, вы используете компилятор C ++ для компиляции кода C.

...