C: amortized cost of a growing array
A fixed-size C array cannot grow, so programs that do not know their size in advance keep a pointer to heap memory, a size, and a capacity. When size reaches capacity, the program allocates a larger block, copies the elements across, and frees the old block.
C
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int *data;
size_t size;
size_t capacity;
long copies;
} IntList;
static void add(IntList *list, int value) {
if (list->size == list->capacity) {
size_t bigger = list->capacity == 0 ? 1 : list->capacity * 2;
int *grown = malloc(bigger * sizeof *grown);
if (grown == NULL) {
exit(1);
}
for (size_t i = 0; i < list->size; i++) {
grown[i] = list->data[i];
list->copies++;
}
free(list->data);
list->data = grown;
list->capacity = bigger;
}
list->data[list->size++] = value;
}
int main(void) {
IntList list = {NULL, 0, 0, 0};
for (int i = 1; i <= 16; i++) {
add(&list, i);
}
printf("appends=16 copies=%ld\n", list.copies);
printf("copies per append=%.4f\n", (double)list.copies / 16);
free(list.data);
return 0;
}