Выделение массива строк

Я пытаюсь создать массив для хранения нескольких строк. Максимальный размер строки равен 100.

Вот как выглядит моя структура:

typedef struct
{
  int size;

  int capacity;

  char** elements;

} array_strings;

Я выделяю место для пустого массива в следующей функции:

array_strings *array_strings_new()
{
    array_strings *vec;

    vec = (array_strings *)malloc(sizeof(array_strings));
    if (vec == NULL)
        return NULL;

    vec->size = 0;
    vec->capacity = 0;
    vec->elements = NULL;

    return vec;
}

И затем я пытаюсь вставить элементы в конец вектора с помощью следующей функции:

int array_strings_insert(array_strings *vec, char *string, int pos)
{
    int i;

    if (vec == NULL || pos < -1 || pos > vec->size)
        return -1;

    /* increases capacity if needed */
    if (vec->size == vec->capacity)
    {
        if (vec->capacity == 0)
            vec->capacity = 1;
        else
            vec->capacity *= 2;


vec->elements = (char **)realloc(vec->elements, vec->capacity *sizeof(char *));
        for (int i = 0; i < vec->capacity; i++)
        {
            vec->elements[i] = realloc(vec->elements[i], 100*sizeof(char));
        }
        if (vec->elementos == NULL)
            return -1;
    }

    /* if pos=-1 inserts at the end of the array */
    if (pos == -1)
        pos = vec->size;

    /* Copy elements from pos to pos+1 until the end of the array */
    for (i = vec->size - 1; i >= pos; i--)
    {
        strcpy(vec->elements[i + 1], vec->elements[i]);
    }

    /* copy string */
    strcpy(vec->elements[pos], string);

    vec->size++;

    return pos;
}

Когда я пытаюсь вставить строку, я получаю "realloc(): недопустимый указатель Прервано (сброшено ядро)".

Может кто-нибудь сказать мне, что я делаю неправильно?

Спасибо,


Я пытался сделать это:

vec->elements = (char **)realloc(vec->elements, vec->capacity *sizeof(char *));
        for (int i = 0; i < vec->capacity; i++)
        {
            vec->elements[i] = NULL; 
            vec->elements[i] = realloc(vec->elements[i], 100*sizeof(char));
        }
        if (vec->elementos == NULL)
            return -1;
    }

И я больше не получаю «realloc (): недопустимый указатель, прерванный (сброс ядра)». Однако первые элементы массива почему-то пусты.

vec->elements[i] не является нулевым после realloc. Вы не можете realloc сразу после выделения.
KamilCuk 28.05.2019 12:53

Как мне тогда выделить каждый vec->elements[i]?

MiguelL 28.05.2019 12:57

Вы не можете вызвать realloc, прежде чем сначала вызвать alloc.

Alex Lop. 28.05.2019 12:57

Вы распределяете их нормально. Вы должны установить vec->elements[i] = NULL перед вызовом realloc(vec->elements[i], .... Значит, нужно сохранить старую емкость. Затем перераспределить. Затем инициализируйте все элементы между старой емкостью и новой емкостью NULL. Затем вы можете вызвать realloc для вновь выделенных указателей.

KamilCuk 28.05.2019 12:57

@KamilCuk Я пытался сделать то, что вы предложили и прокомментировали ниже. Я делаю это правильно?

MiguelL 28.05.2019 13:06

@AlexLop, где я должен использовать malloc, если я не знаю, сколько строк мне понадобится?

MiguelL 28.05.2019 13:07

И да и нет. У вас происходит утечка памяти при втором входе в функцию. Если vec->elements уже содержит несколько указателей, vec->elements[i] = NULL произойдет утечка памяти.

KamilCuk 28.05.2019 13:07

@MiguelL На самом деле вы можете инициализировать указатель значением NULL, а затем вызвать realloc, в таком случае он будет действовать как обычный malloc.

Alex Lop. 28.05.2019 13:09

Я считаю, что это проблема, которая у меня сейчас. Где я должен инициализировать каждый vec->elements[i] до NULL без утечки памяти? @КамилКук

MiguelL 28.05.2019 13:10

Я попытался сделать это ниже, однако первые элементы массива стираются. @АлексЛоп.

MiguelL 28.05.2019 13:15
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Написанный вами код перераспределения уничтожит сохраненные ранее строки. например в случае увеличения размера данных с 2 до 4 первые 2 строки будут потеряны.

Вы можете изменить часть realloc следующим образом.

int prevcapacity;
if (vec->size == vec->capacity)
{
    prevcapacity = vec->capacity;    
    if (vec->capacity == 0)
        vec->capacity = 1;
    else
        vec->capacity *= 2;

    vec->elements = (char **)realloc(vec->elements, vec->capacity *sizeof(char *));
    for (int i = prevcapacity; i < vec->capacity; i++)
    {
        vec->elements[i] = malloc(vec->elements[i], 100*sizeof(char));
    }
}

В этом случае вы можете использовать malloc для дополнительных выделенных строк. Предыдущие строки будут сохранены.

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