Я только что закончил задачу выделения памяти с помощью текущей программы, которую я пишу, но я не доволен тем, что мне нужно было сделать, чтобы исправить это.Вопрос о распределении памяти/перераспределении
В моей программе я создавал массив структур, перераспределяя пространство для массива каждый раз, когда я хотел добавить к нему структуру. Вот общая версия моей структуры и функции, которая бы добавить на структуру в массив:
typedef struct Example {
const char* name;
int (*func)(int, int);
int bool_switch;
}
int add_struct_to_array(Example **example_array, int *ex_array_size, int name, int (*func)(int, int), int bool_switch)
{
// first, make a new struct
Example *new_example = (Example *) calloc(1, sizeof(Example));
if(new_example != NULL) {
new_example->name = name;
new_example->func = func;
new_example->bool_switch = bool_switch;
(*ex_array_size)++;
} else {
printf("Errror allocating %s\n", name);
exit(-1);
}
// now, realloc the array of structs and add the new member to it
Example **temp_example_array = (Example**)realloc(example_array, (*ex_array_size) * sizeof(Example*));
if(temp_example_array != NULL) {
example_array = temp_example_array;
example_array[ (*ex_array_size) - 1 ] = new_example;
} else {
printf("Reallocation failed\n")
exit(-1);
}
return 0;
}
И вот здесь я бы назвал функции (обратите внимание, как я сначала выделить массив структур, Потому что вот где проблема была)
#include "example_struct.h"
int main(int argc, char **argv)
{
int ex_array_size = 0;
Example **example_array = (Example**)calloc(0, sizeof(Example*));
add_struct_to_array(example_array, &ex_array_size, "name", &function, 1);
...
...
add_struct_to_array(example_array, &ex_array_size, "other_name", &other_func, 0);
/* Do stuff here */
example_array_free(example_array);
return 0;
}
в своем невежестве, я, видимо, считал, что выделение массива с размером 0 будет нормально, так как она изначально была пуста, и я мог бы добавить к нему структур после этого. Очевидно, что это не сработало, я получаю ошибки времени выполнения около error for object 0x100100080: pointer being reallocated was not allocated
. example_array
был по адресу 0x100100080
, и первая структура, которую я выделил бы, была бы по адресу 0x100100090
, а после нескольких перераспределений example_array
закончится.
Итак, наконец, на мой вопрос. Я решил эту проблему, выделив больше места для моего example_array
, чем мне нужно, но это кажется очень неэлегантным. Есть лучший способ сделать это?
** EDIT **
Итак, от взглядов большинства ответов, я не должен быть с помощью указателей на указатели. Итак, я пробую это несколько иначе, смешивая ответы pmg
и crypto
. Вот мой код прямо сейчас:
/* example_struct.h */
int add_struct_to_array(Example *example_array, int *ex_array_size, int name, int (*func)(int, int), int bool_switch)
{
Example temp_example_array = realloc(example_array, ((*ex_array_size) + 1) * sizeof(Example));
if(temp_example_array != NULL) {
example_array = temp_example_array;
Example new_example;
new_example.name = name;
new_example.func = func;
new_example.bool_switch = bool_switch;
example_array[ (*ex_array_size) ] = new_example;
++(*ex_array_size);
} else {
fprintf(stderr, "Error reallocating for %s", name);
exit(-1);
}
return 0;
}
/* main.c */
...
...
#include "example_struct.h"
int main(int argc, char **argv)
{
int ex_array_size = 0;
Example *example_array = NULL;
add_struct_to_array(example_array, &ex_array_size, "name", &func, 1);
add_struct_to_array(...);
...
add_struct_to_array(example_array, &ex_array_size, "other name", &other_func, 0);
example_free(example_array);
}
Все компилирует и realloc
«s хорошо, но у меня есть проблемы с доступом к структурам в массиве.
/* main.c */
...
...
#include "example_struct.h"
int main(int argc, char **argv)
{
int ex_array_size = 0;
Example *example_array = NULL;
add_struct_to_array(example_array, &ex_array_size, "name", &func, 1);
add_struct_to_array(...);
...
add_struct_to_array(example_array, &ex_array_size, "other name", &other_func, 0);
printf("%s\n", example_array[0].name) /* Segfault */
example_free(example_array);
}
Еще раз спасибо за помощь.
Зачем нужен указатель на указатель на пример? Одного указателя достаточно, чтобы сделать как можно больше «массива». – pmg
Не следует ли использовать строку 2 в функции add_struct_to_array() (пример *) как typecast, а не (пример *)? – 2010-09-18 15:42:10
Совет. Вам не нужно явно указывать void *, возвращаемый calloc, malloc или realloc. Прочитайте это: http://stackoverflow.com/questions/1835193/is-it-a-better-practice-to-typecast-the-pointer-returned-by-malloc – 2010-09-18 15:53:11