Как увеличить указатель или массив в C во время выполнения (не зная конечной длины во время компиляции)

Я хочу увеличить массив во время выполнения (без указания длины с помощью macos)

у меня есть следующие вопросы

  1. можно ли это сделать с массивом?
  2. Если нет, я должен использовать указатель на int?

Я попробовал следующий код (и ожидал 012 в качестве вывода), но получил 000

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

int main()
{
    int *arr = NULL; 
    size_t n = 0; 
    for (int i = 0; i < 3; ++i) { 
        arr = realloc(arr, (n + 1) * sizeof *arr); 
        arr[n++] = i; 
        printf("%d", *arr);
    } 
}

Ваш код realloc в порядке (простой, но хороший). Вы хотите: printf(" %d",arr[n - 1]); печатать текущий элемент, а не [всегда] первый.

Craig Estey 21.02.2023 22:40

*arr — первый элемент в arr

stark 21.02.2023 22:41

... или printf( "%d: %d and n = %d\n", i, arr[i], n ); Полезно показывать ссылку вместо черного ящика. (PS: Престижность за использование realloc() без типичного первого malloc(). Молодец!) И... Не забудьте free(), чтобы быть чистым... :-)

Fe2O3 21.02.2023 22:42

Предложение: звонки на realloc платные. Увеличьте свой массив в два раза, а не увеличивайте его каждый раз на единицу, чтобы свести к минимуму перераспределение.

Chris 21.02.2023 22:44

@ecjb Подробно, в C массив не может изменить размер после его определения. Размер выделения памяти для хранения массива может меняться.

chux - Reinstate Monica 21.02.2023 23:01

еще одна вещь, вы должны проверить возвращаемое значение realloc, чтобы убедиться, что это удалось, прежде чем пытаться записать в память (вы в настоящее время надеетесь), которую он вам дал.

yano 21.02.2023 23:06

@yano Достоин «ответа», демонстрирующего, что исходный указатель не должен быть перезаписан вызовом функции ???

Fe2O3 21.02.2023 23:19

@Chris: использование коэффициента роста 1,5 вместо 2 может быть лучше. См. этот вопрос для получения дополнительной информации: Какова идеальная скорость роста для динамически выделяемого массива?

Andreas Wenzel 21.02.2023 23:27

@ Fe2O3 уже ответил, но, возможно, это можно было бы включить в ответ ниже.

yano 21.02.2023 23:30
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
9
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

У ОП в основном это есть.

Он просто печатает первый элемент каждый раз.

    // printf("%d", *arr);
    printf("%d", arr[n-1]);

можно ли это сделать с массивом?

Нет. В C массив не может изменить размер после его определения.

Однако размер памяти, выделенной и на которую ссылается указатель, может измениться.

То, как вы перераспределяете массив, прекрасно, хотя и неэффективно. Причина, по которой вы не получаете ожидаемого результата, заключается в том, что вы выводите первый элемент 3 раза.

Рекомендуется размещать массивы за один раз, если вы заранее знаете конечную длину, в других случаях, когда большие массивы необходимо перераспределять на лету, рекомендуется перераспределять с использованием возрастающих размеров в геометрической прогрессии:

Вот пример использования золотого сечения:

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

int main() {
    char *arr = NULL; 
    size_t size = 0;
    size_t pos = 0;
    int c;
    while ((c = getchar()) != EOF) {
        if (pos + 1 > size) {
            // increase size by a ratio of 1.625
            // with an offset to handle the initial case without a test
            size_t new_size = size + (size >> 1) + (size >> 3) + 32;
            char *new_arr = realloc(arr, sizeof(*arr) * new_size);
            if (new_arr == NULL) {
                fprintf(stderr, "cannot reallocate array for %zu bytes\n", new_size);
                free(arr);
                return 1;
            }
            arr = new_arr;
            size = new_size;
        }
        arr[pos++] = c;
    }
    if (arr == NULL) {
        fprintf(stderr, "empty file\n");
        return 1;
    }
    arr[pos] = '\0';
    char *new_arr = realloc(arr, sizeof(*arr) * (pos + 1));
    if (new_arr != NULL) {
        arr = new_arr;
        size = pos + 1;
    }
    /* more code to handle full buffer */
    free(arr);
    return 0;
}
size + (size >> 1) + (size >> 3) прикольно, такое ощущение, что я нашла золотую монету. Просто из любопытства, почему число 32. Просто произвольно? Не похоже, что это имеет какое-либо последующее значение (не учитывая тот факт, что оно функционирует как начальное значение, если size == 0).
Erdal Küçük 22.02.2023 04:09

@ErdalKüçük: правильно, + 32 - это простое смещение для обработки исходного случая без ветвей.

chqrlie 22.02.2023 07:42

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