Как динамически выделять массив целых чисел в C

Часть моего кода C показана ниже.

int data[10]={1,3,6,8,1,7,9,1,1,1}; b=10; int out[b]; process(data, &b, out); alpha (out, b); 

data и out являются массивами int. Процесс функции принимает данные массива, длина которого указана b (= 10) и выполняет математическую операцию, а затем возвращает массив, длина которого снова возвращается b (неизвестно и, следовательно, требуется динамическое выделение). Затем массив выводится с функцией alpha. Прямо сейчас функция alpha всегда отправляет [10], поскольку b была объявлена ​​как 10 во второй строке кода. Как я могу выделить массив динамически, чтобы он содержал только достоверные данные, возвращаемые после процесса функции.

Вам нужно знать разницу между динамическими и статическими распределениями.

Существует 3 варианта:

  • Статическое распределение:

Вы должны заранее знать длину массива. Это должно быть число, а не переменная:

 int out[10]; 

Массив статичен и локально ограничен. Поэтому, если вы это сделаете:

 function do_something() { int out[10]; } 

вы не можете использовать внешний массив вне функции. Но вы можете определить внешний вид и отправить его следующим образом:

 function do_something(int* out) { // do things } ... { int out[10]; do_something(out); } 
  • Автоматическое распределение

Когда вы это сделаете

 int b = 100; int out[b]; 

(который не будет компилироваться на gcc без флага -std = c99 или -std = c11), вы получаете автоматическую переменную, что очень удобно, если вы не используете вне сферы действия, но может быть немного опасным. Получившийся массив генерируется в стеке и уничтожается, когда он выходит из сферы действия (поэтому он может вызвать у вас проблемы, если вы используете его свободно). См. https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Variable-Length.html.

Мы предлагаем вам использовать:

  • Динамическое распределение

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

 int b=100; int* out = (int*) malloc(b * sizeof(int)); // do things with out free(out); 

ОЧЕНЬ ВАЖНО: Не изменяйте значение указателя . Если вы это сделаете, вы не освободите необходимый объем памяти. Хорошая вещь – скопировать указатель и использовать скопированный адрес бесплатно:

  int b=100; int* out = (int*) malloc(b * sizeof(int)); int* out_copy = out; // do things with out. don't touch out_copy free(out_copy); 
 int *out; out=(int *) malloc(sizeof(int) * 10); 

Это приведет к созданию массива out integer типа с размером 10.

Вам нужно быть указателем, а не массивом, и вам нужно передать указатель на функцию, точно так же, как вы делаете с b .

Пример:

 void f(int **a, int *size) { *a = malloc(23 * sizeof(**a)); *size = 23; } /* ... */ int *p = NULL; int b = 0; f(&p, &b); /* 'p' has been allocated and 'b' has its size. */