Я пытаюсь создать массив для хранения нескольких строк. Максимальный размер строки равен 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, прежде чем сначала вызвать alloc.
Вы распределяете их нормально. Вы должны установить vec->elements[i] = NULL перед вызовом realloc(vec->elements[i], .... Значит, нужно сохранить старую емкость. Затем перераспределить. Затем инициализируйте все элементы между старой емкостью и новой емкостью NULL. Затем вы можете вызвать realloc для вновь выделенных указателей.
@KamilCuk Я пытался сделать то, что вы предложили и прокомментировали ниже. Я делаю это правильно?
@AlexLop, где я должен использовать malloc, если я не знаю, сколько строк мне понадобится?
И да и нет. У вас происходит утечка памяти при втором входе в функцию. Если vec->elements уже содержит несколько указателей, vec->elements[i] = NULL произойдет утечка памяти.
@MiguelL На самом деле вы можете инициализировать указатель значением NULL, а затем вызвать realloc, в таком случае он будет действовать как обычный malloc.
Я считаю, что это проблема, которая у меня сейчас. Где я должен инициализировать каждый vec->elements[i] до NULL без утечки памяти? @КамилКук
Я попытался сделать это ниже, однако первые элементы массива стираются. @АлексЛоп.





Написанный вами код перераспределения уничтожит сохраненные ранее строки. например в случае увеличения размера данных с 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 для дополнительных выделенных строк. Предыдущие строки будут сохранены.
vec->elements[i]не является нулевым послеrealloc. Вы не можетеreallocсразу после выделения.