Возможно ли увеличить массив символов при его использовании БЕЗ malloc?

#c #arrays #pointers #char

#c #массивы #указатели #символ

Вопрос:

У меня есть массив символов, мы знаем, что размер символа равен 1 байту. Теперь мне, конечно, нужно собрать некоторый char -> getchar() и одновременно увеличить массив на 1 байт (без malloc, только библиотека: stdio.h)

Моим предложением было бы указать на массив и каким-то образом увеличить этот массив на 1, пока не останется больше символов для получения Или у вас не закончится память…

Ответ №1:

Возможно ли увеличить массив символов при его использовании БЕЗ malloc?

Нет.

Вы не можете увеличить размер массива фиксированного размера.

Для этого вам нужен realloc() из <stdlib.h >, который, похоже, вам «не разрешено» использовать.

Ответ №2:

Возможно ли увеличить char массив при его использовании БЕЗ malloc ?

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

Забавный ответ: Не используйте malloc() , используйте realloc() .

Длинный ответ:

Если char массив имеет статический или автоматический класс хранения, скорее всего, невозможно увеличить его размер во время выполнения, потому что сохранение его по тому же адресу потребует перемещения или перераспределения объектов, присутствующих на более высоких адресах, в другом месте.

Если массив был получен с помощью malloc , возможно, удастся увеличить его размер, если после него в памяти не было выделено никаких других объектов. Действительно, realloc() больший размер может возвращать тот же адрес. Проблема в том, что это невозможно предсказать, и если realloc возвращает другой адрес, текущее пространство было освобождено, поэтому указатели на него теперь недействительны.

Эффективный способ продолжить это перераспределение — увеличить размер геометрически, в 2 раза, 1,5 x, 1,625x за раз … чтобы минимизировать количество перераспределений и сохранить линейное время по мере линейного роста размера массива. Вы бы использовали другую переменную для выделенного размера массива и количества символов, которые вы сохранили в нем.

Вот пример:

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

int main(void) {
    char *a = NULL;
    size_t size = 0;
    size_t count = 0;
    int c;

    while ((c = getchar()) != EOF amp;amp; c != 'n') {
        if (count >= size) {
            /* reallocate the buffer to 1.5x size */
            size_t newsize = size   size / 2   16;
            char *new_a = realloc(a, new_size);
            if (new_a == NULL) {
                fprintf("out of memory for %zu bytesn", new_size);
                free(a);
                return 1;
            }
            a = new_a;
            size = new_size;
        }
        a[count  ] = c;
    }

    for (i = 0; i < count; i  ) {
        putchar(a[i]);
    }
    free(a);
    return 0;
}
  

Ответ №3:

Есть два способа создать пространство для строки без использования динамического выделения памяти (malloc …). Вы можете использовать статический массив или массив с автоматической продолжительностью хранения, вам нужно указать максимальную сумму, которую вы, возможно, никогда не достигнете. Но всегда проверяйте это.

 #define BUFFER_SIZE 0x10000
  

Статический

 static char buffer[BUFFER_SIZE];
  

Или автоматически (вам нужно убедиться, что BUFFER_SIZE меньше размера стека)

 int main() {
    char buffer[BUFFER_SIZE];
    ...
};
  

Операционная система также выполняет оптимизацию. Это может привести к ленивому распределению всего (статического / автоматического) буфера, так что в физической памяти будет находиться только используемая часть. (Это также относится к функциям динамического выделения памяти.) Я обнаружил, что calloc (для больших блоков) просто выделяет виртуальную память для программы; страницы памяти очищаются только при обращении к ним (возможно, через некоторые прерывания, вызванные процессором). Я сравнил это с распределением с помощью malloc и memset. Memset выполняет ненужную работу, если программа обращается не ко всем байтам / страницам буфера.

Если вы не можете выделить буфер с помощью malloc …, создайте статический / автоматический массив достаточного размера и позвольте операционной системе выделить его для вас. Он не занимает столько же места в двоичном файле, потому что он просто сохраняется как размер.