So, if I were to malloc 500 bytes, then use setjmp to save the state, then free the 500 bytes, then longjmp, would I be able to access those 500 bytes? For example:
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
jmp_buf buf;
struct str {
char s[200];
int a;
};
int main() {
struct *str = (struct str *)malloc(sizeof(str));
(*str).s = "the string";
(*str).a = 31;
setjmp(buf);
printf("%s %d\n", (*str).s, (*str).a);
free(str);
longjmp(buf, 1);
printf("%s %d\n", (*str).s, (*str).a);
return 0;
}
What will be the output of the second printf? Also, what's the meaning of the second argument in longjmp? I saw some people use large integers as the second argument.
No,
setjmp()saves some CPU register values as well as some context to allow the program to resume execution at the same place under a very strict set of conditions.Note that you do not allocate enough memory for a
struct str: you passsizeof(str), which is the size of thestrpointer. You should write this instead:Futhermore, you cannot initialize
str->swith an assignment, you should define thestrmember as aconst char *instead of an array.No, your program has undefined behavior because the memory block allocated by
mallocand pointed to bystrhas been freed, thusstrmust not be dereferenced any longer.Note that the last 2 statements in the
mainfunction will never execute becauselongjmp()does not return, it makes the program resume execution at the place wheresetjmp()returns and it makessetjmpreturn the value of the second argument passed tolongjmp()(and the value1if0is passed for this argument).Here is a modified version for illustration:
Output (compiled with optimisations):
Output (compiled with
-O0):As you can see, what gets preserved by
setjmp()is difficult to predict so this function must be used with extreme caution in circumstances where the programmer is well aware of the compiler behavior and only for very specific needs.