Подтвердить что ты не робот

Куча выделяет 2D-массив (не массив указателей)

Я пишу C-код, и я бы хотел, чтобы heap выделил 512 * 256 байт. Для моего удобства я хотел бы иметь доступ к элементам с синтаксическим массивом [a] [b]; нет арифметики, чтобы найти правильный индекс.

Каждый учебник, который я вижу в Интернете, подсказывает мне создать массив указателей, которые указывают на массивы строк, которые я хочу в моем массиве. Это означает, что каждый подмассив должен быть malloc'd и free'd индивидуально. Меня интересует решение, для которого требуется только один вызов malloc и один вызов на бесплатный. (Таким образом, все элементы смежны) Я думаю, что это возможно, потому что я не буду создавать зубчатый массив.

Я был бы признателен, если бы кто-нибудь мог использовать синтаксис для объявления такого массива.

4b9b3361

Ответ 1

Ну, если вы хотите выделить массив типа, вы назначаете его в указатель этого типа.

Так как 2D-массивы представляют собой массивы массивов (в вашем случае массив из 512 массивов из 256 символов), вы должны назначить его в указатель на массив из 256 символов:

char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;

(Скобки вокруг *arr должны сделать его указателем на массив, а не массив указателей)

Ответ 2

Если вы выделяете такой массив, для этого требуется два вызова free, но он позволяет синтаксис стиля array[a][b] и является непрерывным.

char **array = malloc(512 * sizeof(char *));
array[0] = malloc(512*256);
for (int i = 1; i < 512; i++)
    array[i] = array[0] + (256 * i);

См. array2 здесь для получения дополнительной информации: http://c-faq.com/aryptr/dynmuldimary.html

Ответ 3

Это легко предположить, что вам не нужна совместимость с древним стандартом C89 (среди текущих компиляторов C только для MSVC и нескольких встроенных компиляторов). Вот как вы это делаете:

int (*array)[cols] = malloc(rows * sizeof *array);

Тогда array[a][b] справедливо для любого a в [0,rows) и b в [0,cols).

В языке стандарта C array имеет измененный тип. Если вы хотите передать указатель на другие функции, вам нужно будет повторить этот тип в списке аргументов функции и убедиться, что по меньшей мере число столбцов передается функции (так как это необходимо как часть измененного с изменением тип).

Изменить: Я пропустил тот факт, что OP заботится только о фиксированном размере 512x256. В этом случае C89 будет достаточным, и все, что вам нужно, это:

int (*array)[256] = malloc(512 * sizeof *array);

Точный же тип может использоваться в списках аргументов функции, если вам нужно передать указатель между функциями (а также как возвращаемый тип функции, но для этого использования вам может понадобиться typedef it...: -)

Ответ 4

Поскольку вы знаете размер массива загодя, вы можете создать тип struct, содержащий массив 521x256, а затем динамически выделить struct.

Ответ 5

Если вы знаете размер массива, вы можете typedef его и сделать указатель на него. Вот короткий фрагмент, демонстрирующий это использование:

#include <stdio.h>
#include <stdlib.h>

typedef int array2d[20][20];

int main() {
    int i,j;
    array2d *a = malloc(sizeof(array2d));
    for(i=0;i!=20;i++)
        for(j=0;j!=20;j++)
            (*a)[i][j] = i + j;

    for(i=0;i!=20;i++)
        for(j=0;j!=20;j++)
            printf("%d ",(*a)[i][j]);
    free(a);
    return 0;
}

Ответ 6

Можно динамически выделять один и тот же тип многомерного массива, который

static char x[512][256];

дает вам, но это довольно сложно из-за распада типа. Я знаю только, как это сделать с помощью typedef:

typedef char row[512];
row *x = malloc(sizeof(row) * 256);

Это позволяет определить размер второго измерения во время выполнения. Если оба измерения могут меняться во время выполнения, вам нужен вектор допинга.