C - изменить 2D массив во время выполнения - PullRequest
0 голосов
/ 01 января 2019

Как можно изменить 2D-массив во время выполнения в C?Например, мы первоначально объявили массив unsigned char [20] [500], а позже нам нужно изменить его форму, например, на массив [40] [250].Общее потребление памяти будет (и должно) всегда оставаться неизменным (10.000 байт).

Ограничение состоит в том, что массив новой формы должен находиться по точному адресу пространства памяти - как было первоначально объявлено.Мы не можем выделить другое пространство / мы не уверены, будет ли какое-либо свободное пространство для использования (проект микропроцессора).Я пытался с Calloc, но в конце концов он идет бананы:

unsigned char **my_array; //Global defined

void reshape(unsigned short max_cols, unsigned short max_rows){
    my_array = (unsigned char **) calloc(max_cols, sizeof(unsigned char*));
    for(i = 0; i < max_cols; ++i){
        my_array[i] = (unsigned char **) calloc(max_rows, sizeof(unsigned char));
    }
}

Я новичок в C, поэтому любая помощь приветствуется - спасибо!

Ответы [ 2 ]

0 голосов
/ 01 января 2019

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

Итак, используя глобалы (некрасиво), что-то вроде:

unsigned char *my_data; // allocate to have enough space, 10000 chars or whatever

unsigned char **my_array; //Global defined

void reshape(unsigned short max_cols, unsigned short max_rows) {
    free(my_array); // don't leak memory

    // no need for cast below
    // also, since array will be initialized below, use malloc
    my_array = malloc(max_cols * sizeof(unsigned char*)); 

    // initialize my_data with addresses of rows
    for(i = 0; i < max_cols; ++i) {
        my_array[i] = &(my_data[i * max_rows]);
    }
}

Хотя учтите, что если вам не нужно, чтобы my_array был массивом указателей, вы можете избежать косвенного обращения, напрямую обращаясь к mydata, например:

my_data[row_index * max_cols + column_index]
0 голосов
/ 01 января 2019

Изменение формы массива может быть выполнено с помощью приведения:

char (*p)[FirstColumns] = calloc(FirstRows, sizeof *p);
// Test p and handle error if NULL.
char (*q)[SecondColumns] = (char (*)[SecondColumns]) p;

Пока базовые элементы одного типа, проблем с наложением не должно быть.

(Педантичная интерпретация Cможет возникнуть вопрос, нарушает ли доступ к массиву SecondColumns, который изначально был массивом FirstColumns, или его части, или перекрывает несколько, правила псевдонимов, но к массивам на самом деле не обращаются через их значения l, поскольку их значения l преобразуются в указатели. Я не знаю ни одного компилятора, который создает проблемы с таким кодом.)

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