Step 4 of 10
calloc and strdup-style copies
calloc
calloc(count, size) allocates room for count elements of size bytes each, and sets every byte to zero. Use it when you want a clean starting state, like counters or a grid. Standard libraries also check that count * size doesn't overflow (returning NULL if it would), which malloc(count * size) can't do for you.
Copying a string onto the heap
A very common job: keep your own copy of a string, for example text that came from a temporary buffer. The recipe:
- Measure it with
strlen. - Allocate
strlen(s) + 1bytes. The +1 is for the'\0', and forgetting it is one of the most common bugs in C. - Copy the characters, including the terminator (
strcpyormemcpywith the +1).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *shout(const char *s) {
size_t n = strlen(s);
char *out = malloc(n + 2);
if (out == NULL) {
return NULL;
}
memcpy(out, s, n);
out[n] = '!';
out[n + 1] = '\0';
return out;
}
int main(void) {
char *msg = shout("hello");
if (msg == NULL) {
return 1;
}
printf("%s (%zu chars)\n", msg, strlen(msg));
free(msg);
int *counts = calloc(3, sizeof *counts);
if (counts == NULL) {
return 1;
}
printf("%d %d %d\n", counts[0], counts[1], counts[2]);
free(counts);
return 0;
}
hello! (6 chars)
0 0 0
shout needs n + 2 bytes: n characters, the !, and the terminator. Counting bytes carefully like this is everyday C.
(Many systems have strdup, which does steps 1 to 3 for you. It's standard since C23, but writing it yourself is good practice.)
Your turn: write char *copy_string(const char *s) that returns a new heap copy of s.
Previous: Return heap memory from a function Next: Growing with realloc