Undefined Behavior & Safety

reading an uninitialized variable

When you reserve a notepad page to scribble on, the page is not blank — it still has whatever was printed or scribbled there before. Declaring a local variable in C without giving it a value is like grabbing such a page: the variable occupies memory that already held something, and that leftover content is what you read if you use the variable before assigning to it. Beginners often assume a fresh variable starts at zero. For local variables, it does not.

Precisely: a local (automatic) variable that you declare but do not initialize has an indeterminate value, and reading it is undefined behavior in most cases. It is tempting to think this just gives you a 'random number', but it is worse than that — because it is undefined behavior, the compiler may assume the read never happens and optimize on that basis, so the result is not even guaranteed to be a consistent leftover value; the same variable can appear to hold different things on different reads. There are honest exceptions: variables with static storage duration (globals, and locals declared static) ARE zero-initialized by the standard, and memory from calloc is zeroed. But malloc does NOT zero its memory, and a plain local on the stack is not zeroed either — so 'int count;' followed by 'count++;' reads garbage.

Why this matters: uninitialized reads cause bugs that are maddening because they are non-deterministic — the program may work in a debug build (which sometimes zeroes memory) and fail in a release build, or work on one run and crash on the next. The discipline is simple and cheap: initialize every variable at the point you declare it, even to a harmless default like 0 or NULL. Compilers will warn about many such reads if you enable warnings (gcc -Wall -Wextra), and tools like MemorySanitizer or Valgrind catch the ones the compiler misses.

int count; /* local, NOT zeroed */ count++; /* reads an indeterminate value: UB */ int total = 0; /* fixed: initialize at declaration */ static int g; /* static storage: guaranteed 0 */ int *p = malloc(4); /* malloc does NOT zero; *p is garbage */ int *q = calloc(1, 4); /* calloc DOES zero; *q is 0 */

Locals and malloc'd memory are not zeroed; static storage and calloc'd memory are. Initialize locals at declaration.

A fresh local variable is NOT zero — only static-storage variables and calloc are guaranteed zero. Worse, reading an indeterminate value is UB, so it is not even a stable 'random' number; the compiler may give different results each read.

Also called
indeterminate valuegarbage value未初始化變數不確定值