Можно ли увеличить массив символов при его использовании, БЕЗ malloc? - PullRequest
2 голосов
/ 07 апреля 2019

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

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

Ответы [ 3 ]

3 голосов
/ 07 апреля 2019

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

номер

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

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

2 голосов
/ 07 апреля 2019

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

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

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

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

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

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

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

Вот пример:

#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 && 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 bytes\n", 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;
}
0 голосов
/ 07 апреля 2019

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

#define BUFFER_SIZE 0x10000

Статический

static char buffer[BUFFER_SIZE];

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

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

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

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

...