【发布时间】:2020-10-16 06:30:13
【问题描述】:
我正在尝试在 c 中实现一个数组列表。
typedef struct ArrayList {
size_t len;
size_t size;
int arr[1];
} ArrayList;
我有一个函数可以在数组满时重新分配它。
void array_list_push(ArrayList* list, int num) {
if (list->len == list->size) {
size_t size = list->size;
size *= 2;
printf("%ld\n", size); // It prints the size
list = realloc(list, size * 2 + (sizeof(ArrayList) - 1 * sizeof(int)));
list->size = size;
}
list->arr[list->len++] = num;
}
这里是“测试”功能。
#include <stdio.h>
#include "array_list.h"
int main() {
ArrayList *list = array_list_create(2);
unsigned i, j;
for(i = 0; i < 32; i++)
{
array_list_push(list, i); // side-effect: prints the size. for ""debugging""
printf("[");
for(j=0; j < array_list_get_length(list); j++)
printf("%d, ", array_list_get(list, j));
printf("]\n");
}
return 0;
}
还有输出:
[0, ]
[0, 1, ]
4
[0, 1, 2, ]
[0, 1, 2, 3, ]
8
[0, 1, 2, 3, 4, ]
[0, 1, 2, 3, 4, 5, ]
[0, 1, 2, 3, 4, 5, 6, ]
[0, 1, 2, 3, 4, 5, 6, 7, ]
16
realloc(): invalid next size
Aborted (core dumped)
为什么会出现这个错误,为什么前 2 次重新分配没有失败?
这里是array_list_create
ArrayList* array_list_create(size_t initial_size) {
ArrayList *list = malloc(sizeof(ArrayList) + sizeof(int) * (initial_size - 1));
list->len = 0;
list->size = initial_size;
return list;
}
根据Nate Eldredge's answer更改我的realloc函数后,我得到以下输出:
[0, ]
[0, 1, ]
4
[0, 1, 2, ]
[0, 1, 2, 3, ]
8
[]
[5, ]
[5, 6, ]
[5, 6, 7, ]
[5, 6, 7, 8, ]
[5, 6, 7, 8, 9, ]
[5, 6, 7, 8, 9, 10, ]
[5, 6, 7, 8, 9, 10, 11, ]
[5, 6, 7, 8, 9, 10, 11, 12, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, 741875756, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, 741875756, 539769120, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, 741875756, 539769120, 539766833, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, 741875756, 539769120, 539766833, 539767089, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, 741875756, 539769120, 539766833, 539767089, 539767345, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, 741875756, 539769120, 539766833, 539767089, 539767345, 926495541, ]
[5, 6, 7, 8, 9, 10, 11, 12, 539768155, 924855350, 741875756, 539769120, 539766833, 539767089, 539767345, 926495541, 892418102, ]
等等乱码。我尝试使用./main > output 将其重定向到一个文件中,并且在编辑器中它显示出奇怪的?s。这是cat output的输出
?
[5, 6, 7, 8, 9, ]
[5, 6, 7, 8, 9, 10, ]
[5, 6, 7, 8, 9, 10, 11, ]
[5, 6, 7, 8, 9, 10, 11, 12, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, ]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ]
【问题讨论】:
-
size * 2在realloc表达式中是怎么回事?看起来好像你假设sizeof(int) == 2但它可能不是。 -
你真的坚持使用 C89 吗? C99 有灵活的数组成员,这将使这个更干净。
-
能否提供
array_list_create以及编译程序所需的所有工具?
标签: c89