I know this is dangerous behavior, I just want to find out what happened.
The code is as follows:
#include<stdio.h> #include<stdlib.h> static int count = 0; void hello(void){ count ++; fprintf(stderr,"hello! %d\n",count); } void foo(void){ void *buf[10]; static int i; for(i = 0 ; i < 100 ; i++){ // put enough data to overwrite the return address on stack buf[i] = hello; } } int main(void){ int buf[1000]; foo(); return 0; }
And the result:
…… hello! 83 hello! 84 hello! 85 hello! 86 hello! 87 hello! 88 hello! 89 Segmentation fault (core dumped)
Why was hello func called 89 times? When foo returns, the pc register gets the address hello func, right? So hello, and do what is inside. So what? Hasn't the program returned to the main function? Where did 89 come from? I have to misunderstand something, please indicate.
hello foo 90 , buf. foo , ( ) hello , "" . , " ", , .
hello
foo
buf
hello , foo. , , foo hello . , hello , , , , hello.
hello, , , hello hello , .
, , , , , , , , . hello , .
, undefined. - , "" .
, ( 89 ). , , .
( , , .)
As Nachum says, this behavior is undefined, but this does not mean that it cannot be explained:
100 - 89 = 11
This is exactly the size of your local stack (void * [10] + int).
Try this (undefined behavior, may delete your hard drive or fix global savings):
#include<stdio.h> #include<stdlib.h> static int count = 0; static void hello(void){ count ++; fprintf(stderr,"hello! %d\n",count); } static void foo(void){ void *buf[1]; static int i; for(i = 0 ; i <= 100 + 2; i++){ // put enough data to overwrite the return address on stack buf[i] = hello; } } static void bye(void) { printf("Bye, bye...\n"); exit(EXIT_SUCCESS); } int main(void){ void *buf[1000]; int i; for (i = 0; i < 1000; ++i) { buf[i] = &bye; } foo(); return 0; }