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

// Append добавляет элемент el в конец массива arr.
// size - размер массива arr
// last_ix - индекс последнего элемента в массиве. 
// Индекс последнего элемента может быть 3, но размер массива может быть 10.
// Возвращает код ошибки, если что-то пошло не так.
int Append(
	int el,
	int** arr, // двойной указатель, так как внутри функции мы будем менять сам указатель
	int* size, // указатель, так как в функции мы меняем размер массива
	int* last_ix // указатель, так как в функции мы инкрементируем индекс последнего элемента в массиве
) {
	if (*last_ix >= *size) { // если больше нет свободного места в массиве, то
		*size *= 2; // увеличим размер массива в два раза
		int* arr2 = malloc(*size * sizeof(int)); // выделим новый кусок памяти, который в два раза больше
    // Если malloc не смог выделить память, например она реально вся занята
    // То мы возвращаем -1 как код ошибки и завершаем выполнение функции
		if (!arr2) return -1;
		
		// Копируем содержимое старого массива в новый массив
		for (int i = 0; i < *last_ix; i++) {
			arr2[i] = (*arr)[i]; // скобки при разыменовании нужны, так как * имеет меньший приоритет, чем []
		}

		// Очистим память, которую занимает старый массив. Мы уже скопировали данные.
		free(*arr);
    // теперь перезапишем укзатель на массив так, чтобы он указывал на новую область памяти
    // ради этого присвоения мы сделали для массива двойной указатель
		*arr = arr2;
	}

	// разыменуем указатель на массив, возьмем last_ix элемент в массиве и положим туда el
	(*arr)[*last_ix] = el; // скобки при разыменовании нужны, так как * имеет меньший приоритет, чем []
	*last_ix += 1;

	return 0; // так как всё хорошо, вернем код ошибки 0
}

// Print красиво печатает содержимое массива в консоль
void Print(int* arr, int size, int last_ix) {
	for (int i = 0; i < size; i++) {
		printf("arr[%d]=%d ", i, arr[i]);
	}
	printf("last_ix=%d size=%d\\n", last_ix, size);
}

int main(void) {
  // Создадим небольшой массив на 2 элемента.
  // Далее мы автоматически с помощью Append будем увеличивать его размер
	int size = 2;
	int last_ix = 0;
	int* arr = malloc(size * sizeof(int));

	Print(arr, size, last_ix);
	Append(42, &arr, &size, &last_ix);
	Print(arr, size, last_ix);
	Append(14, &arr, &size, &last_ix);
	Print(arr, size, last_ix);
	Append(10, &arr, &size, &last_ix);
	Print(arr, size, last_ix);
	Append(15, &arr, &size, &last_ix);
	Print(arr, size, last_ix);
	Append(18, &arr, &size, &last_ix);
	Print(arr, size, last_ix);
	Append(100, &arr, &size, &last_ix);
	Print(arr, size, last_ix);
}