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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
525
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Is it possible to increase char array while using it, WITHOUT malloc?

Нет.

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

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

Ответ принят как подходящий

Is it possible to increase char array while using it, WITHOUT malloc?

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

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

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

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

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

Эффективный способ продолжить это перераспределение — увеличить размер геометрически, на коэффициент за раз, 2x, 1,5x, 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 && 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;
}

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

#define BUFFER_SIZE 0x10000

Статический

static char buffer[BUFFER_SIZE];

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

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

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

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

Другие вопросы по теме