typedef struct {
void **head;
size_t used_size;
size_t free_size;
size_t current_size;
size_t size_increment;
} GrowingArray;
GrowingArray createEmptyGrowingArray(int initial_size, int size_increment) {
GrowingArray empty_growing_array;
empty_growing_array.head = malloc(initial_size * sizeof(void *));
empty_growing_array.used_size = 0;
empty_growing_array.free_size = initial_size;
empty_growing_array.current_size = initial_size;
empty_growing_array.size_increment = size_increment;
return empty_growing_array;
}
GrowingArray appendToGrowingArray(GrowingArray growing_array, void *new_element) {
void *new_head_of_array;
if (growing_array.free_size == 0) {
new_head_of_array = realloc(growing_array.head, (growing_array.current_size + growing_array.size_increment) * sizeof(void*));
if (new_head_of_array == NULL) {
printf("Reallocation failure.\n");
}
growing_array.free_size = growing_array.size_increment;
growing_array.current_size += growing_array.size_increment;
growing_array.head = new_head_of_array;
}
growing_array.head[growing_array.used_size++] = new_element;
growing_array.free_size--;
return growing_array;
}
void finalizeGrowingArrayMemory(GrowingArray growing_array) {
growing_array.head = realloc(growing_array.head, growing_array.current_size * sizeof(void *));
}
void freeGrowingArray(GrowingArray growing_array) {
free(growing_array.head);
}
int main(int argc, char* argv[]) {
GrowingArray test_array = createEmptyGrowingArray(5, 1);
int *test_integer = (int *)malloc(1 * sizeof(int));
*test_integer = 4;
int *another_integer = (int *)malloc(1 * sizeof(int));
*another_integer = 6;
int *yet_another_integer = (int *)malloc(sizeof(int));
*yet_another_integer = 9;
test_array = appendToGrowingArray(test_array, test_integer);
test_array = appendToGrowingArray(test_array, another_integer);
test_array = appendToGrowingArray(test_array, yet_another_integer);
finalizeGrowingArrayMemory(test_array);
printf("%x,", *(int *)test_array.head[0]);
printf("%x,", *(int *)test_array.head[1]);
printf("%x\n", *(int *)test_array.head[2]);
freeGrowingArray(test_array);
printf("Going to free %llx\n", (long long int)test_integer);
free(test_integer);
printf("Going to free %llx\n", (long long int)another_integer);
free(another_integer);
printf("Going to free %llx\n", (long long int)yet_another_integer);
free(yet_another_integer);
return 0;
}
我写这些代码基于在正确答案提供对这个问题的示例代码:How may I implement a generic, dynamically growing array in C?
提供的答案包括简单地重新分配指针数组的函数。预期的用法是在将几个项目附加到数组之后调用它,如答案的代码所示。
我想知道为什么应该这样做。它提供了什么好处? realloc()是否尝试根据之前的使用情况预测一块内存将被使用,然后将其移动到它认为最好的地方?
谢谢!
作为附加是或不是问题:我应该使用calloc()
而不是malloc()
里面的createEmptyGrowingArray()
?
注意,如果阵列总是由** **因子扩展(即乘以大小1.2,1.5,或甚至2),单个元件的插入将具有摊销的运行时间** O(1) **即恒定。如果使用上述代码中的常量增量,则添加新元素的运行时间为'O(n)'! –