c - Function returns unexpected pointer -


i'm working on simple c program nested structures , unions, , got problem returning pointer char array.

here code :

#define bufsize 32  typedef enum {   s1 = 0,   s2 } type_t;  typedef struct {   int x, y;   char value[bufsize]; } s1_t;  typedef struct {   s1_t s;   char value2[bufsize]; } s2_t;  typedef struct {   type_t t;   union {     s1_t s1;     s2_t s2;   }; } s3_t;  s3_t* new_s1(int x, int y, char* value) {   s3_t* s;   if ((s = malloc(sizeof(s3_t))) == null)     return null;   memset(s, 0, sizeof(s3_t));   s->t = s1;   s->s1.x = x;   s->s1.y = y;   strncpy(s->s1.value, value, bufsize);   return s; }  s3_t* new_s2(int x, int y, char* value, char* value2) {   s3_t* s;   if ((s = malloc(sizeof(s3_t))) == null)     return null;   memset(s, 0, sizeof(s3_t));   s->t = s2;   s->s2.s.x = x;   s->s2.s.y = y;   strncpy(s->s2.s.value, value, bufsize);   strncpy(s->s2.value2, value2, bufsize);   return s; }  // problem comes function ? char* get_value(s3_t s) {   return (s.t == s1) ? s.s1.value : s.s2.s.value; }  int main(void) {   s3_t *a, *b;   char *p1, *p2;   if ((a = new_s1(1, 2, "a")) == null)     return 1;   if ((b = new_s2(1, 2, "abcd", "val2")) == null)     return 2;   p1 = get_value(*a);   printf("a (%p) => p1 : (%p - %s) - (%p - %s)\n", a, p1, p1, a->s1.value, a->s1.value);   p2 = get_value(*b);   printf("b (%p) => p1 : (%p - %s) - (%p - %s)\n", b, p2, p2, b->s2.s.value, b->s2.s.value);   printf("strcmp(p1,p2) = %d\n", strcmp(p1, p2));   free(a);   free(b);   return 0; } 

and output :

a (0x1974010) => p1 : (0x7fff085df16c - a) - (0x197401c - a) b (0x1974070) => p2 : (0x7fff085df16c - abcd) - (0x197407c - abcd) strcmp(p1,p2) = 0 

the problem pointers returned get_value function same, if params not ("a", "b"), strcmp() returns 0. see, get_value(*a) returns pointer 0x7fff085df16c, why not 0x197401c ?

because pointers returned same, if change main in :

// ... p1 = get_value(*a); p2 = get_value(*b); printf("a (%p) => p1 : (%p - %s) - (%p - %s)\n", a, p1, p1, a->s1.value, a->s1.value); printf("b (%p) => p2 : (%p - %s) - (%p - %s)\n", b, p2, p2, b->s2.s.value, b->s2.s.value); printf("strcmp(p1,p2) = %d\n", strcmp(p1, p2)); // ... 

the string value of p1 overwritten string value of p2. output looks :

a (0x1156010) => p1 : (0x7fffb81d8cbc - abcd) - (0x115601c - a) b (0x1156070) => p2 : (0x7fffb81d8cbc - abcd) - (0x115607c - abcd) strcmp(p1,p2) = 0 

of course, can fix changing function get_value make copy string , return pointer.

char* get_value(s3_t s) {   char* p;   if ((p = malloc(bufsize)) == null)     return null;   strncpy(p, ((s.t == s1) ? s.s1.value : s.s2.s.value), bufsize);   return p; } 

but don't (and want to) understand why pointer returned get_value different pointer in structure. did miss ?

structure/union types (all types, really) in c passed by-value.

so in code:

char* get_value(s3_t s) {  } 

the compiler allocate s3_t on stack , caller copy contents stack space allocated.

by returning contents of s.s1.value, you're returning pointer space allocated on stack. memory gets deallocated when get_value() returns caller.

some compilers kind enough warn when make error. example, took get_value() clang -wall , got following:

$ /opt/llvm+clang-3.4/bin/clang -wall  -o pbv.o -c pbv.c  pbv.c:28:24: warning: address of stack memory associated local variable 's' returned [-wreturn-stack-address]   return (s.t == s1) ? s.s1.value : s.s2.s.value;                        ^ 1 warning generated. 

Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -