How to allocate memory with malloc

Check size, then allocate

Before multiplying a count by an element size, ensure the product fits in size_t. malloc returns uninitialized storage or null; include stdint.h and stdlib.h.

if (count > SIZE_MAX / sizeof(int)) {
    fprintf(stderr, "Requested array is too large\n");
    return 1;
}
int *values = malloc(count * sizeof *values);
if (values == NULL && count != 0) {
    fprintf(stderr, "Allocation failed\n");
    return 1;
}

Initialize before reading

Bytes returned by malloc have indeterminate values. Assign every element before reading it, or use calloc when all-bits-zero initialization is appropriate.

for (size_t i = 0; i < count; ++i) {
    values[i] = 0;
}

Resize without losing memory

Check the new size first. realloc may move storage and returns null without freeing the original block, so assign it to a temporary pointer.

if (new_count > SIZE_MAX / sizeof *values) {
    free(values);
    return 1;
}
int *resized = realloc(values, new_count * sizeof *values);
if (resized == NULL && new_count != 0) {
    free(values);
    return 1;
}
values = resized;

Free exactly once

Release every successful allocation once when no pointer will use it again. Never free stack memory, interior pointers, or the same allocation twice.

free(values);
values = NULL;