c - struct assignment: segment fault 11 -
#include <stdio.h> #include <string.h> #include <stdlib.h> union value { long long i; unsigned long long u; double d; long double ld; void *p; void (*g) (); }; struct foo { struct { union value max; union value min; }limits; }; struct bucket_info { void *p; // free position void *limit; // end position struct bucket_info *next; // next bucket }; #define nodes 8192 void * my_malloc(size_t size) { void *p = malloc(size); if (!p) exit(1); memset(p, 0, size); return p; } void * alloc_bucket(size_t size) { struct bucket_info *pb; pb = my_malloc(sizeof(struct bucket_info) + size); pb->p = pb + 1; pb->limit = (char *)pb->p + size; return pb; } void * alloc_for_size(struct bucket_info *s, size_t size) { void *ret; while (s->next) s = s->next; if ((char *)s->p + size > (char *)s->limit) { struct bucket_info *pb = alloc_bucket(size * nodes); s->next = pb; s = pb; } ret = s->p; s->p = (char *)s->p + size; return ret; } static void * alloc_node(struct bucket_info **s, size_t size) { if (!*s) *s = alloc_bucket(size * nodes); return alloc_for_size(*s, size); } static struct bucket_info *foo_info; void * alloc_foo_node() { void *ret = alloc_node(&foo_info, sizeof(struct foo)); return ret; } struct foo * new_foo() { return alloc_foo_node(); } void test(int t, struct foo *foo1) { struct foo *foo2 = new_foo(); // crash @ line *foo2 = *foo1; // comment switch statement, works. why? switch (t) { case 1: break; default: break; } } int main(int argc, const char * argv[]) { struct foo *foo1 = new_foo(); test(10, foo1); return 0; }
above complete code. , i've compiled clang, got 'segment fault 11' @ line:
*foo2 = *foo1;
then, change line to:
memcpy(foo2, foo1, sizeof(struct foo));
it works.
then i've tried compiled these 2 cases gcc, there no problem.
the value returned alloc_foo_node
may not correctly aligned struct foo
.
on system, printing _alignof(struct foo)
gives 16
, pointers foo1
, foo2
not multiples of 16
.
so causes undefined behaviour convert unaligned result of alloc_foo_node
have type struct foo *
.
to fix have muck around lot more allocation code, make sure ever hands out space on correct boundary struct foo
. use max_align_t
(it defined _alignof(max_align_t)
biggest possible alignment required).
Comments
Post a Comment