🇯🇵 日本語 | 🇺🇸 English

Quiz (Dynamic Memory)

Test your understanding of malloc/free, dangling pointers, memory leaks, and calloc.

Question 1 — malloc basics

int *p = (int *)malloc(sizeof(int) * 3);
p[0] = 10; p[1] = 20; p[2] = 30;
printf("%d\n", p[1]);
free(p);

What does this print?

10
20
30
Compile error
Explanation: malloc(sizeof(int)*3) allocates space for 3 ints on the heap. p[1] is the second element → 20.

Question 2 — Access after free

int *p = (int *)malloc(sizeof(int));
*p = 42;
free(p);
printf("%d\n", *p);

What happens?

42
0
Undefined behavior (dangling pointer)
Compile error
Explanation: Accessing memory through a pointer after free (a dangling pointer) is undefined behavior.
The old value may still look intact, but that's never guaranteed. The safe habit is to set p = NULL; immediately after free.

Question 3 — Memory leak

void func(void) {
    int *p = (int *)malloc(sizeof(int) * 100);
    *p = 42;
    // forgot free(p)
}

What's the problem here?

Compile error
Runtime error
Memory leak (runs, but memory is never released)
Nothing is wrong
Explanation: When the function returns without calling free, the pointer is lost and the allocated memory can never be returned to the heap.
That's a memory leak. The program still runs, but calling this function repeatedly will eventually exhaust available memory.

Question 4 — calloc vs malloc

int *a = (int *)calloc(5, sizeof(int));
printf("%d %d %d\n", a[0], a[2], a[4]);
free(a);

What does this print?

Garbage values
0 0 0
Compile error
Segmentation Fault
Explanation: Unlike malloc, calloc zero-initializes the allocated memory.
So the output is 0 0 0. Reach for calloc whenever you want zero-initialized memory.

Question 5 — Double free

int *p = (int *)malloc(sizeof(int));
*p = 10;
free(p);
free(p);  // free the same pointer again

What happens?

Runs fine
Compile error
Undefined behavior (crash or heap corruption)
The second free is ignored
Explanation: Calling free on an already-freed pointer is undefined behavior (a double free).
  • On most platforms it crashes the program or corrupts the heap's internal state
  • It can even turn into a security vulnerability (arbitrary code execution)
Prevention: set the pointer to NULL right after freeing it. free(NULL) is safe — the standard guarantees it's a no-op.

Question 6 — sizeof on a dynamic array

// Pointer is 8 bytes, int is 4 bytes
int *p = (int *)malloc(sizeof(int) * 10);
printf("%lu\n", sizeof(p));

What does this print?

40 (10 ints)
10
8 (size of a pointer)
4
Explanation: p is a pointer variable, so sizeof(p) returns the size of the pointer itself.
  • Unlike with arrays, sizeof can't tell you the size of a malloc'd region
  • On 64-bit systems a pointer is typically 8 bytes
You have to track the allocated size yourself in a variable — malloc doesn't report it back.

Question 7 — How realloc behaves

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?

Which statement about q after realloc is correct?

q always points to the same region as p, so it is safe to use
If the region was moved, q becomes invalid (using it is undefined behavior)
q is automatically updated after realloc
q is always set to NULL
Explanation: If realloc can't extend the existing region in place, it copies the data to a new location and frees the old one.
  • If it extends in place, the same address is returned → q is still valid
  • If the block is moved, the old address stored in q has been freed, so q is invalid (a dangling pointer)
  • Whether it moves is implementation-defined and unpredictable
After calling 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;.

Question 8 — malloc failure

int *p = (int *)malloc(sizeof(int) * 1000000000);
*p = 42;  // no NULL check

What happens if memory allocation fails?

p is automatically filled with a valid pointer
Compile error
p becomes NULL, and *p causes a segmentation fault
0 is assigned to *p
Explanation: When malloc fails it returns NULL.
  • Dereferencing *p without a NULL check crashes the program
  • Always follow up with if (p == NULL) { /* handle error */ }
The safe form is:
int *p = malloc(...);
if (p == NULL) {
    fprintf(stderr, "Out of memory\n");
    return 1;
}

Question 9 — free(NULL)

int *p = NULL;
free(p);  // free a NULL pointer
printf("OK\n");

What happens?

Segmentation fault
Nothing happens, "OK" is printed
Compile error
Undefined behavior
Explanation: The standard guarantees that free(NULL) is a no-op.
  • You can call free without a NULL check, which simplifies error-handling code
  • There's no need for an if (p != NULL) free(p); guard
Freeing a pointer that was already freed (not NULL, but invalid) is still undefined behavior. The safe idiom is to set p = NULL; right after each free.

Result

Answer all the questions to see your score.
Home