Я в настоящее время пытаюсь понять, как реализовать 2-мерный массив структуры в C. Мой код отказывает все время, и я действительно собираюсь позволить ему закончиться как все мои подходы, получающие фирму к C: мусор. Это - то, что я получил:
typedef struct {
int i;
} test;
test* t[20][20];
*t = (test*) malloc(sizeof(test) * 20 * 20);
Моя великолепная ошибка:
ошибка: несовместимые типы при присвоении для ввода ‘теста структуры * [20]’ от типа ‘тест структуры *’
Я должен выделить память отдельно для каждого 2-го размера? Я становлюсь гаек. Это должно быть настолько просто. Однажды я создам машину времени и намагничу некоторые дискеты компилятора C...
Этого должно быть достаточно:
typedef struct {
int i;
} test;
test t[20][20];
Это объявит двумерный массив test
размером 20 x 20. Нет необходимости использовать malloc.
Если вы хотите динамически распределить свой массив, вы можете сделать это:
// in a function of course
test **t = (test **)malloc(20 * sizeof(test *));
for (i = 0; i < 20; ++i)
t[i] = (test *)malloc(20 * sizeof(test));
Кроме того, пока размер вашего внутреннего измерения постоянен, вы можете выделить переменное количество отсчетов этого внутреннего измерения
int n = ...;
test (*t)[20] = malloc(sizeof (*t) * n);
t[0 .. (n-1)][0 .. 19] = ...;
test **t;
t = (test **)malloc(sizeof(test *) * 20);
for (i = 0; i < 20; i++) {
t[i] = (test *)malloc(sizeof(test) * 20);
}
Другие ответы показывают, как это исправить, но не объясняют почему. Как намекнул компилятор, тип t
в вашем исходном примере на самом деле test *[20]
, поэтому вашего приведения к test *
было недостаточно.
В C имя массива T размерности N на самом деле имеет тип *T[dim0][dim1]...[dimN-1]
. Весело.
По моим наблюдениям, вы можете не знать точно, чего хотите, и запутать арифметику структур и указателей. Пожалуйста, выберите следующие 2 возможности.
1) Двумерный массив с каждым элементом имеет указатель на test
.
В этом случае память всех указателей на test
s уже статически выделена .
Но, память реальных тестов
s не готова.
В этом случае вы должны заполнить тест [i] [j]
один за другим.
Каждый из тестов
дискретен в памяти, и вы можете создавать или уничтожать их индивидуально динамически.
typedef struct {
int i;
} test;
test* t[20][20];
/* or instead of statically allocated the memory of all the pointers to tests
you can do the following to dynamically allocate the memory
test ***t;
t = (test***)malloc(sizeof(test *) * 20 * 20);
*/
for (int i=0; i < 20; i++){
for (int j=0; j < 20; j++){
t[i][j] = malloc(sizeof(test));
}
}
2) Двумерный массив с каждым элементом - это тест
.
В этом случае память всех тестов
уже выделена .
Также память реальных тестов
s готова к использованию без дополнительной подготовки.
Все тесты
непрерывны в памяти как большой блок и всегда там. Это означает, что вы можете потратить впустую часть памяти, если вам нужны только все тесты
в определенное время пиковой нагрузки, и большую часть времени вы используете только некоторые из них.
typedef struct {
int i;
} test;
test t[20][20];
/* or instead of statically allocated the memory of all tests
you can do the following to dynamically allocate the memory
test **t;
t = (test**)malloc(sizeof(test) * 20 * 20);
*/