Subject: Breakthrough cure discovered, Alzheimers and Dementia

From: Alzheimer's Cure Found <[email-masked]>
Date: Mon, 27 Oct 2014 07:56:30 -0800

[Alzheimer's Research Center] 
An Amazing Breakthrough.

There has not been an update of this magnitude in a long time.

We know you wouldn't want anything more than for them to have their memories back.

We are here to tell you that they CAN have their memories back. New ground-breaking research has been found pinpoints enzyme that terminates brain receptors and kinases of the brain. This proven research can reverse the effects of Dementia and Alzheimer's and reclaim memories. 

http://www.pudsmoky.com/upend/tiresome/amphitheater/shunpiking/exorcises.pl

YA ALZ Research Center | 2014 | #53345

4-Barron St, Chester, AR-72943 | All removal requests can be sent to http://www.pudsmoky.com/knowledgeable/statuting/laureled/protecting/agricultures.cfm

Thank You

You were right, your teacher was completely wrong. Proceed with caution in this class.   Andrew Medico Oct 17 at 14:11
4	 	
You should have asked, what about a[27][270]? a[270][270]?   axiom Oct 17 at 14:15
14	 	
a[27][27] happens to be 0 by chance. If a is a global or a static variable the chances are high that you get zero because all global and static variables are initialized to zero before program start, and if there are more global/static variables after a, a[27][27] just happens to be one of these variables. But basically it's of course undefined behaviour.   Michael Walz Oct 17 at 14:18 
6	 	
I would complain that the question is unanswerable in the context of a C language course, finding out what will actually happen would require examining the compiled objects and looking at the behaviour. Such a question would be far more appropriate for a reverse engineering class.   Vality Oct 17 at 15:08
9	 	
Don't forget to give your teacher a link to this question! :-)   Mark Garcia Oct 18 at 1:44
show 11 more comments
7 Answers
activeoldestvotes
up vote
40
down vote
accepted
You were right: it is undefined behavior and you cannot count it always producing 0.

As for why you are seeing zero in this case: modern operating systems allocate memory to processes in relatively coarse-grained chunks called pages that are much larger than individual variables (at least 4KB on x86). When you have a single global variable, it will be located somewhere on a page. Assuming a is of type int[][] and ints are four bytes on your system, a[27][27] will be located about 500 bytes from the beginning of a. So as long as a is near the beginning of the page, accessing a[27][27] will be backed by actual memory and reading it won't cause a page fault / access violation.

Of course, you cannot count on this. If, for example, a is preceded by nearly 4KB of other global variables then a[27][27] will not be backed by memory and your process will crash when you try to read it.

Even if the process does not crash, you cannot count on getting the value 0. If you have a very simple program on a modern multi-user operating system that does nothing but allocate this variable and print that value, you probably will see 0. Operating systems set memory contents to some benign value (usually all zeros) when handing over memory to a process so that sensitive data from one process or user cannot leak to another.

However, there is no general guarantee that arbitrary memory you read will be zero. You could run your program on a platform where memory isn't initialized on allocation, and you would see whatever value happened to be there from its last use.

Also, if a is followed by enough other global variables that are initialized to non-zero values then accessing a[27][27] would show you whatever value happens to be there.

share|improve this answer
edited Oct 18 at 14:04

answered Oct 17 at 14:26

Andrew Medico
12.5k82647
3	 	
No, you cannot assume that. Depending on compiler options it may fail to compile or it may cause a runtime error. It's also possible that other code automatically linked into your program (e.g. the C runtime library) that runs before main will happen to use that area as scratch space and put some non-zero value there.   Andrew Medico Oct 17 at 14:39
1	 	
Where are you getting 3000 from? &a[27][27] == (&a[0][0] + (27 * 4) + 27) == &a[0][0] + 135 and if sizeof(int) == 4, then 135 * sizeof(int) == 540 bytes offset from the beginning of the array.   bcrist Oct 18 at 8:33
1	 	
@AndrewMedico It depends on what level of abstraction you are working on. If you are working on the language level then you are right to say you cannot assume it. If you are working on the OS level, things change.   Paul Manta Oct 18 at 17:14 
1	 	
@SantiSantichaivekin No, but static values are typically stored in the .bss section. The OS will initialize this entire section with zeros. The language doesn't know about .bss, but the OS does. If you are certain your program will always run under an OS that uses a .bss section then you are safe to make some assumptions that the language alone does not allow you to.   Paul Manta Oct 19 at 23:26 
2	 	
@PaulManta Even "C program running on an OS that zeroes .bss" does not guarantee that non-faulting out-of-bounds reads will produce 0. Going outside the bounds of your own variables means you might read non-zero global variables used by your C runtime library or (on Windows) non-zero values written by AppInit DLLs.   Andrew Medico Oct 20 at 1:25
show 5 more comments

up vote
19
down vote
Accessing an array out of bounds is undefined behavior, which means the results are unpredictable so this result of a[27][27] being 0 is not reliable at all.

clang tell you this very clearly if we use -fsanitize=undefined:

runtime error: index 27 out of bounds for type 'int [4][4]'
Once you have undefined behavior the compiler can really do anything at all, we have even seen examples where gcc has turned a finite loop into an infinite loop based on optimizations around undefined behavior. Both clang and gcc in some circumstances can generate and undefined instruction opcode if it detects undefined behavior.

Why is it undefined behavior, Why is out-of-bounds pointer arithmetic undefined behaviour? provides a good summary of reasons. For example, the resulting pointer may not be a valid address, the pointer could now point outside the assigned memory pages, you could be working with memory mapped hardware instead of RAM etc...

Most likely the segment where static variables are being stored is much larger then the array you are allocating or the segment that you are stomping though just happens to be zeroed out and so you are just lucky in this case but again completely unreliable behavior. Most likely your page size is 4k and access of a[27][27] is within that bound which is probably why you are not seeing a segmentation fault.

What the standard says

The draft C99 standard tell us this is undefined behavior in section 6.5.6 Additive operators which covers pointer arithmetic which is what an array access comes down to. It says:

When an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression.

[...]

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

and the standards definition of undefined behavior tells us that the standard imposes no requirements on the behavior and notes possible behavior is unpredictable:

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, [...]