Arrays, Strings, Pointers, and Memory
Arrays occupy consecutive elements
Section titled “Arrays occupy consecutive elements”#include <stdio.h>
int main(void) { int values[5] = {10, 20, 30, 40, 50}; size_t count = sizeof(values) / sizeof(values[0]);
for (size_t index = 0; index < count; index++) { printf("index=%zu value=%d address=%p\n", index, values[index], (void *)&values[index]); } return 0;}Observe address differences. Each element is adjacent, but the numerical difference reflects sizeof(int), not one byte.
Index 5 is outside this five-element array. C does not insert a general runtime bounds check. Reading it creates undefined behavior: the language no longer promises a meaningful result, even when one run appears harmless.
Strings need a terminator
Section titled “Strings need a terminator”char word[] = "frog";This array contains five bytes: f, r, o, g, and zero. Functions such as strlen search for that \0 terminator. If a supposed string lacks one within valid storage, the function continues reading beyond the object.
Pointers store addresses
Section titled “Pointers store addresses”int value = 42;int *pointer = &value;printf("value=%d address=%p through-pointer=%d\n", value, (void *)pointer, *pointer);&value obtains the address; pointer stores it; *pointer accesses the pointed-to integer. The pointer and integer are different objects with different sizes and jobs.
Inside a function parameter, an array expression usually becomes a pointer. sizeof(parameter) then reports pointer size, not the original array length. Pass lengths explicitly.
Knowledge check
Question 1 of 3
Knowledge check complete
You answered all 3 questions correctly.
What this gives us as researchers
Section titled “What this gives us as researchers”You can now reason about the boundaries that make C powerful and dangerous: contiguous storage, explicit lengths, terminators, and addresses. The C Memory Lab checks this model before we investigate unfamiliar code.