Re: Question about setjmp on Itanium HPUX.
From: Richard Bos (rlb_at_hoekstra-uitgeverij.nl)
Date: 11/19/04
- Next message: Lawrence Kirby: "Re: i need help with this card game!"
- Previous message: Peter Smithson: "Re: Initializing array of structure!!"
- In reply to: Peter Smithson: "Re: Question about setjmp on Itanium HPUX."
- Next in thread: Peter Smithson: "Re: Question about setjmp on Itanium HPUX."
- Reply: Peter Smithson: "Re: Question about setjmp on Itanium HPUX."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Fri, 19 Nov 2004 10:27:09 GMT
Peter Smithson <pgsmithson_deletethisbit@yahoo.co.uk> wrote:
> #include <stdio.h>
> #include <setjmp.h>
> #include <malloc.h>
No such header in ISO C. Use <stdlib.h> instead.
> struct mystruct {
> char abc;
> jmp_buf s_jbuf;
> };
>
> #define ALLIGN 8
>
> int main()
> {
> struct mystruct s_x;
This is correct.
> struct mystruct *p_x = (void *)
> ((char *)malloc(sizeof(struct mystruct)+ALLIGN)+ALLIGN);
*Kablooie!* Yes, that was the sound of the alignment of your struct
being blown to bits. You do not know that a jmp_buf needs to be aligned
on 8 bytes or a whole fraction of 8 bytes. You do know that the pointer
returned from malloc() is correctly aligned for all types, including
jmp_buf and your struct. Therefore, you do not know that (that pointer+8
bytes) is correctly aligned for either. And _that_ means that...
> printf("Doing setjmp 2...\n");
> setjmp(p_x->s_jbuf);
...passing this quite probably incorrectly aligned pointer to setjmp()
causes undefined behaviour.
You can solve this by either not adding anything to malloc()'s return
value, or adding a number of bytes which you know will preserve correct
alignment.
In the first case, you write just
struct mystruct *p_x = malloc(sizeof *p_x + ALLIGN);
and use the last ALLIGN (btw, the correct spelling is ALIGN) bytes for
whatever extra data you need instead of the first ones. However, do note
that if you use them for anything but chars, you end up with the same
potential alignment problems as you have now.
In the second case, you need to find out a safe value for the addition.
The one value which you are guaranteed is safe for struct mystruct is
sizeof(struct mystruct); this _must_ be good enough, since in an array,
each element is sizeof(struct mystruct) beyond the previous. So in this
case, you write
#define ALIGN sizeof(struct mystruct)
struct mystruct *p_x=
(void *)((char *)malloc(sizeof *p_x+ALIGN) + ALIGN);
or even, more simply,
struct mystruct *p_x=malloc(2*sizeof *p_x)+1;
since you're now in effect dealing with an array of two struct elements.
Note that in this case, as in your original code, you need to remember
to subtract the extra amount of memory when you free() it.
This problem is not specific to either setjmp() or your implementation,
btw. Your code is simply not conforming; it would cause problems for any
type with a strict enough alignment, on any implementation that cares
about alignment.
Richard
- Next message: Lawrence Kirby: "Re: i need help with this card game!"
- Previous message: Peter Smithson: "Re: Initializing array of structure!!"
- In reply to: Peter Smithson: "Re: Question about setjmp on Itanium HPUX."
- Next in thread: Peter Smithson: "Re: Question about setjmp on Itanium HPUX."
- Reply: Peter Smithson: "Re: Question about setjmp on Itanium HPUX."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|