I'm trying to implement an arraylist in c.
typedef struct ArrayList {
size_t len;
size_t size;
int arr[1];
} ArrayList;
I have a function that reallocates it when the array gets full.
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;
}
Here is the "testing" function.
#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;
}
And the output:
[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)
Why am i getting this error, and why don't the first 2 reallocations fail?
Here's 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;
}
After changing my realloc function according to Nate Eldredge's answer, i get the following output:
[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, ]
And so on with scrambled numbers. I try to redirect it into a file with ./main > output
and in the editor it shows weird ?
s. Here's the output of 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, ]
list = realloc(list, size * 2 + (sizeof(ArrayList) - 1 * sizeof(int)));
This calculation looks wrong. I don't know where the 2 came from but it makes no sense; it ought to be sizeof(int)
. I think it might be clearer to write it as
list = realloc(list, sizeof(ArrayList) + (size - 1)*sizeof(int));