76 Intermediate C Programming
An array is created at line 10 and it has 5 elements. The valid indexes are 0, 1, 2, 3,
and 4. Lines 12 and 13 print the addresses of x, y, and the array. Lines 16, 17, 19, and 21
use incorrect indexes. If we compile, link, and execute this program, we may find that the
values of x or y are changed because we are using incorrect indexes. This is not guaranteed,
and the results will depend on the specific compiler. This is the output when I run this
program:
& x = 0x7fffcabf4e68, & y = 0x7fffcabf4e6c
& arr[0] = 0x7fffcabf4e50, & arr[4] = 0x7fffcabf4e60
x = -2, y = 15
x = -2, y = 15
x = 108, y = 15
x = 108, y = -353
As we can see, x has changed because of this assignment:
arr [6] = 108;19
Similarly, y is changed because of this assignment:
arr [7] = -353;21
In this example, the gcc compiler has reordered the local variables in the call stack. The
addresses of x and y are larger than the addresses of the array elements. Thus, x and y are
changed when the indexes are 6 and 7 respectively. The program uses addresses that are
given to it by the operating system. If we run the above program again, we will likely see
different addresses for x and y. It is possible that neither x nor y, but something else, is
changed due to using the invalid indexes.
The real problem is that the program’s behavior is undefined. What does this mean more
precisely? The effects of wrong indexes may change when the program runs on different
machines. Sometimes, it seems nothing is wrong, even though there is a pernicious error
in the code. Sometimes, the values of x or y may be changed. Sometimes, the program
stops with the message “Segmentation fault (core dumped).” This means that the program
intends to read from or write to a memory address that does not belong to the program.
Modern computers usually run many programs at once. Each program is given part of the
memory. If one program tries to read from or write to a wrong address, the operating system
may stop the program. This protects the other programs running on the same computer.
Be careful about the word “may” here. The operating system does not keep track of
every memory address. Instead, the operating system uses “pages” as a unit. The size of
a page of memory varies on the operating system; 4KB is common. If the wrong address
is within a page given to a program, then the operating system will not stop the program.
That means that a program may modify a variable within a valid page unintentionally
without causing a segmentation fault. In this example, x and y are changed. It is called
a segmentation fault, and not a page fault, because some processors organize memory by
variable sized “segments”. Page and segment may be used together: A segment may contain
multiple pages. In fact, “page fault” is already used in the context of virtual memory. Thus,
the name “segmentation fault” remains. If the wrong address is outside the program’s
segments, then the operating system will stop the program. Try replacing
arr [7] = -353;21
by
arr [7000] = -353;21