Why does the following code not give a segmentation error?

In the next program, should the code in the second loop generate a segmentation error?
Can someone explain why the following code does not give a segmentation error and works as expected?

Conclusion: 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
0 1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1

#include <stdio.h> #define N 20 int main(){ int a[N]; int i; for(i=0;i<N;i++){ a[i]=20-i; printf("%3d ",a[i]); } printf("\n\n"); for(i=0;i<N;i++){ a[i]=a[a[i]]; printf("%3d ",a[i]); } printf("\n\n"); return 0; } 
+4
source share
3 answers

Your array is on the stack. Running over the end usually means that you are accessing the garbage (and therefore invoking undefined behavior), but this will not necessarily result in a seg error.

In your case, the first a[i]=20-i sets the first element to 20. Thus, the first a[i]=a[a[i]] starts access to a[20] , which is just around the corner. But there is a good chance that it really refers to the variable i - provided that the compiler places it immediately after the array - and i is currently zero, so the nett effect will be a[0] = 0 . Each subsequent call a[i]=a[a[i]] guaranteed completely within the boundaries, since a[i] < 20 .

+11
source

Marceloโ€™s commentary seems intuitive, but itโ€™s not really what is happening. The stack grows from high to low. therefore, [19] will be at a higher address, and [0] will be at a lower address. Since I am defined after the array, it will be even lower on the stack. Thus, [20] does not indicate i. This, as others have said, is simply the cost of garbage. a [-1] or [-2] (some compilers allow negative-indexing, which means it goes below) will actually point to i. (-2, because some compilers can put a protective byte (or 4 bytes) after allocating an array to avoid buffer overflow attacks).

+2
source

Pretty sure that this applies to the OS, regardless of whether you crashed, not the compiler. Your mileage may vary between systems and the amount of memory for the stack. And I would suggest that as long as you are in the previously allocated stack space, it will not break. What is especially troublesome - it can run very well and not tell you that there is a problem, in addition, if you are lucky, this leads to erroneous results.

If you try to access, say, a[10000] - what the OS knows is not in your program space - something outside the space allocated for the stack will crash.

+1
source

All Articles