Test your understanding of malloc/free, dangling pointers, memory leaks, and calloc.
int *p = (int *)malloc(sizeof(int) * 3); p[0] = 10; p[1] = 20; p[2] = 30; printf("%d\n", p[1]); free(p);
malloc(sizeof(int)*3) allocates space for 3 ints on the heap. p[1] is the second element → 20.int *p = (int *)malloc(sizeof(int)); *p = 42; free(p); printf("%d\n", *p);
free (a dangling pointer) is undefined behavior.p = NULL; immediately after free.void func(void) { int *p = (int *)malloc(sizeof(int) * 100); *p = 42; // forgot free(p) }
free, the pointer is lost and the allocated memory can never be returned to the heap.int *a = (int *)calloc(5, sizeof(int)); printf("%d %d %d\n", a[0], a[2], a[4]); free(a);
malloc, calloc zero-initializes the allocated memory.calloc whenever you want zero-initialized memory.int *p = (int *)malloc(sizeof(int)); *p = 10; free(p); free(p); // free the same pointer again
free on an already-freed pointer is undefined behavior (a double free).
NULL right after freeing it. free(NULL) is safe — the standard guarantees it's a no-op.
// Pointer is 8 bytes, int is 4 bytes int *p = (int *)malloc(sizeof(int) * 10); printf("%lu\n", sizeof(p));
p is a pointer variable, so sizeof(p) returns the size of the pointer itself.
sizeof can't tell you the size of a malloc'd regionmalloc doesn't report it back.
int *p = (int *)malloc(sizeof(int) * 3); int *q = p; // back up p p = (int *)realloc(p, sizeof(int) * 100); // What happens if we use q now?
q after realloc is correct?realloc can't extend the existing region in place, it copies the data to a new location and frees the old one.
q is still validq has been freed, so q is invalid (a dangling pointer)realloc, you should never use the original pointer — only the new one that realloc returned. Also, if realloc fails it returns NULL without freeing the original, so the safe pattern is tmp = realloc(p, ...); if (tmp) p = tmp;.
int *p = (int *)malloc(sizeof(int) * 1000000000); *p = 42; // no NULL check
*p causes a segmentation fault*pmalloc fails it returns NULL.
*p without a NULL check crashes the programif (p == NULL) { /* handle error */ }int *p = malloc(...);
if (p == NULL) {
fprintf(stderr, "Out of memory\n");
return 1;
}
int *p = NULL; free(p); // free a NULL pointer printf("OK\n");
free(NULL) is a no-op.
free without a NULL check, which simplifies error-handling codeif (p != NULL) free(p); guardp = NULL; right after each free.