c - Unexpected pointer change after deferenced pointer affectation -
one of pointer being changed after deference , affect value. don't understand why, since code in function runned multiple times work of time. here code :
typedef struct s_freelist { int ssize; struct s_freelist *next; struct s_freelist *back; int *esize; } t_freelist; void *addnode(void *addr, size_t size) { t_freelist *freelist; // working stuff freelist = (t_freelist *)addr; freelist->ssize = size * -1; freelist->next = ((t_freelist *)g_startaddr)->next; freelist->back = g_startaddr; ((t_freelist *)g_startaddr)->next->back = freelist; ((t_freelist *)g_startaddr)->next = freelist; // not working stuff printf("addr = %p\nsize = %d\n", addr, (int)size); freelist->esize = addr + size - 4; printf("freelist->esize = %p\n", freelist->esize); *(freelist->esize) = size * -1; printf("freelist->esize = %p\n\n", freelist->esize); return (collapsenodes(addr)); } here output address :
addr = 0x1647020 size = 32 freelist->esize = 0x164703c freelist->esize = 0xffffffe00164703c
from printf output, you're running on platform 64-bit pointers. each pointer has size and, importantly, natural alignment of 8 bytes, gives following layout of structure (offsets in decimal):
00 ssize; 04 <padding> 08 *next; 16 *back; 24 *esize; 32 <total size> you're setting freelist->esize = addr + size - 4, which, size = 32, happens overlap higher portion of esize field itself.
if you're going address arithmetic, try use compiler-provided introspection facilities such sizeof , offsetof wherever possible. may reduce incidence of such errors , make code more readable , more portable.
(or, better yet, avoid address arithmetic @ all).
Comments
Post a Comment