Проблема неправильного размещения 2d-массива - PullRequest
2 голосов
/ 03 февраля 2011

Я все еще плохо знаком с C, malloc и всем этим джазом, поэтому я решил написать это, чтобы выучить некоторые навыки. Идея в том, что я читаю кучу целых из файла и помещаю их в матрицу (2d массив). В начале файла указывается количество строк и столбцов, поэтому он считывает эти числа и использует malloc для настройки массива 2d.

int read_matrix(FILE *mat, int ***Z, int *x, int *y) 
{
    int i = 0;
    int x_temp = 0;
    int y_temp = 0;

    if (fscanf(mat, "%d %d", &(*x), &(*y)) == EOF){
        printf("File is not big enough to contain a matrix\n");
        return -1;
    }

    printf("About to malloc %d\n", *x);

    *Z = (int**) malloc(*x * sizeof(int*));
    while (i < *x) {
        printf("mallocing %d\n", i);
        *Z[i] = (int*) malloc(*y * sizeof(int));
        printf("malloced\n");
        ++i;
    }

    printf("Malloc complete\n");

    /*Other unimportant code*/
}

Вывод гласит:

About to malloc 3 
mallocing 0 
malloced 
mallocing 1
Segmentation fault

Так что это не неправильное выражение ничего, кроме одного int ** в Z .. Я думаю?

Я очень новичок в C, поэтому я не уверен, сделал ли я небольшую ошибку или действительно неправильно все понял. Какие-нибудь мысли? Спасибо!

Ответы [ 3 ]

3 голосов
/ 03 февраля 2011

Оператор [] связывается более тесно, чем унарный оператор *. Попробуйте изменить *Z[i] на (*Z)[i] и посмотрите, будет ли ваш код вести себя.

В качестве примечания, в C также довольно распространено выделение одного массива размером (sizex * sizey) для матрицы, а затем индексирование его как arr [x * sizey + y] или arr [y * sizex + Икс]. Это более точно имитирует то, что делает язык со статическими массивами (например, если вы объявляете int foo[10][10], все 100 int непрерывны в памяти и нигде не хранится список из 10 int *.

2 голосов
/ 03 февраля 2011

Я согласен и с Уолтером, и с Андреем Т.Это просто дополнительная информация.

Обратите внимание, что вы можете обойтись всего двумя malloc() вызовами вместо *x + 1 - одним большим блоком для самих int и одним для индекса строки..

*Z = malloc(*x * sizeof (*Z)[0]);
(*Z)[0] = malloc(*x * *y * sizeof (*Z)[0][0]);
for (i = 1; i < *x; i++) {
    (*Z)[i] = (*Z)[0] + i * *y;
}
1 голос
/ 03 февраля 2011

Как правильно заметил Уолтер в своем ответе, это должно быть (*Z)[i] = ..., а не *Z[i] = ....

Кроме того, я бы предложил избавиться от этого ада разыменования / преобразования типов в вашем исходном коде.,Не разыгрывайте результат malloc.Не используйте имена типов под sizeof.Выражение этого следующим образом

 *Z = malloc(*x * sizeof **Z);
 ...
 (*Z)[i] = malloc(*y * sizeof *(*Z)[i]);

сделает ваш код независимым от типа и намного более читабельным.

Отдельный вопрос - что на Земле заставило вас использовать &(*x) в fscanf.Это какой-то странный стандарт кодирования?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...