Как мне выделить больше места для моего массива st strenss?
Вопрос
Я пытаюсь добавить еще 10 элементов в мою структуру, который уже был Malloc с фиксированным размером 20. Это так, как у меня есть определенная структура:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct st_temp {
char *prod;
};
int main ()
{
struct st_temp **temp_struct;
size_t j;
temp_struct = malloc (sizeof *temp_struct * 20);
for (j = 0; j < 20; j++) {
temp_struct[j] = malloc (sizeof *temp_struct[j]);
temp_struct[j]->prod = "foo";
}
return 0;
}
Так что я имел в виду, было для Realloc как (однако, не уверен, как):
temp_struct = (struct st_temp **) realloc (st_temp, 10 * sizeof(struct st_temp*));
а затем добавьте дополнительные 10 элементов,
for (j = 0; j < 10; j++)
temp_struct[j]->prod = "some extra values";
Как я мог достичь этого? Любая помощь ценится!
Решение
Чтобы избежать утечек памяти, нам нужно обрабатывать перераспределение с осторожностью (больше на этом позже). Функция Realloc:
void *realloc(void *ptr, size_t size)
, куда
ptr
= указатель на оригинал (malloc
блок памяти 'ed) памяти, а также
size
= Новый размер блока памяти (в байтах).
realloc
Возвращает новое расположение динамически выделенного блока памяти (которое, возможно, изменилось) - Или NULL, если переопределение не удалось! Если он возвращает NULL, оригинальная память остается неизменным, поэтому Вы всегда должны использовать временную переменную для возврата значения realloc
.
Примером будет уточнить это немного (в интересующих точках: Syntax Realloc аналогичен Malloc's (нет необходимости для дополнительных отливок и т. Д.), И, после Realloc, вам необходимо создать одни и те же шаги для новых объектов, которые вы делали после Malloc):
struct st_temp **temp_struct;
temp_struct = malloc(20 * sizeof *temp_struct);
if (temp_struct == NULL) { /* handle failed malloc */ }
for (int i = 0; i < 20; ++i) {
temp_struct[i] = malloc(sizeof *temp_struct[i]);
temp_struct[i]->prod = "foo";
}
// We need more space ... remember to use a temporary variable
struct st_temp **tmp;
tmp = realloc(temp_struct, 30 * sizeof *temp_struct);
if (tmp == NULL) {
// handle failed realloc, temp_struct is unchanged
} else {
// everything went ok, update the original pointer (temp_struct)
temp_struct = tmp;
}
for (int i = 20; i < 30; ++i) { // notice the indexing, [20..30)
// NOTICE: the realloc allocated more space for pointers
// we still need to allocate space for each new object
temp_struct[i] = malloc(sizeof *temp_struct[i]);
temp_struct[i]->prod = "bar";
}
// temp_struct now "holds" 30 temp_struct objects
// ...
// and always do remember, in the end
for (int i = 0; i < 30; ++i)
free(temp_struct[i]);
free(temp_struct);
Обратите внимание, что это на самом деле не на самом деле структуры, но и больше массив указателей на структуру - или даже массив массивов структуры, если хотите. В последнем случае каждый подпара будет длиной 1 (так как мы выделим пространство только для одной структуры).
Другие советы
Когда вы используете realloc()
, вы должны дать новый размер вместо количества байтов для добавления. Так:
temp_struct = (struct st_temp **) realloc (temp_struct, 30 * sizeof(struct st_temp*));
30 - это, конечно, ваш оригинал 20 плюс еще 10. То realloc()
Функция заботится о копировании исходных данных в новое место, если ему необходимо переместить блок памяти.
Затем добавление дополнительных 10 элементов было бы что-то вроде (начиная с индекса 20, а не 0):
for (j = 20; j < 30; j++) {
temp_struct[j]->prod = "some extra values";
}