In the following program, shouldn't the开发者_StackOverflow社区 code in the 2nd loop give segmentation fault ?
Can somebody explain why is the following code not giving segmentation fault and working as expected ?Output: 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;
}
Your array is on the stack. Running past the end usually means you're accessing garbage (and therefore invoking undefined behaviour), but it won't necessarily trigger a seg-fault.
In your case, the first a[i]=20-i
sets the first element to the value 20. Thus, the first a[i]=a[a[i]]
triggers an access to a[20]
, which is off the end. But there's a good chance it's actually accessing the variable i
— assuming the compiler places it immediately after the array — and i
is currently zero, so the nett effect would be a[0] = 0
. Every subsequent invocation of a[i]=a[a[i]]
is guaranteed to be completely within bounds, since a[i] < 20
.
Marcelo's comment seems intuitive but that is not actually what's happening. The stack grows from High to Low. so a[19] will be at higher address and a[0] will be at lower address. Since i is defined after the array, it will be even lower on the stack. So a[20] does not point to i. It is as others have mentioned, just a garbage value. a[-1] or a[-2] (some compilers allow indexing with a negative sign which just means it goes lower down) will actually point to i. (-2 because some compilers can put a guard byte (or 4 bytes) after an array allocation to avoid buffer overflow attacks).
Pretty sure it's up to the OS as to whether you seg fault and not the compiler. Your mileage may vary between systems and how much memory is allocated for the stack. And I would guess that as long as your in pre-allocated stack space, it won't crash. That's what's particularly troublesome - it could run along just fine and not tell you that there's a problem, other than if you're lucky it produces erroneous results.
If you'd tried to access, say, a[10000]
- something the OS knows isn't in your programs space - something beyond the space allotted for the stack, it would seg fault.
精彩评论