Sunday, January 2, 2011

simple C example 3: structs

Here's a simple struct example, containing two elements, a char * and an int. We typedef it to be an "A" and then construct one in four different ways: (i) in main, (ii) by calling an auxiliary function, (iii) by assigning the address of the A from (i), and by using malloc in an auxialiary function.

The syntax for access to the member elements is different in the case of a pointer to the struct variable and a struct variable itself.

As you can see from the output, all four approaches give valid A's but the last one has a quite different address. It is on the "heap" rather than on the "stack."

One thing I don't understand is whether examples 2 and 4 are dangerous. Under what circumstances do objects that we obtain from a function go away when those functions return? If you know, I'd be grateful for your insight. [UPDATE: I'm pretty sure example 2 is not something you should do, because after the function returns that memory will be reallocated. I guess we got away with it here because no further allocations were made.]

Output:

I'm an A:  A 1 0x7fff5fbff9b0
me too : A 2 0x7fff5fbff9a0
me three: A 1 0x7fff5fbff9b0
me four : A 3 0x100100080

Code listing:

#include <stdio.h>
#include <stdlib.h>

struct myStruct {
char *s;
int x;
};

typedef struct myStruct A;
A stack_A(char *, int);
A * heap_A(char *, int);

// bad bad bad
A stack_A(char *s, int x) {
A a;
a.x = x;
a.s = s;
return a;
}

A * heap_A(char *s, int x) {
A * p = (A *) malloc(sizeof(A));
p->x = x;
p->s = s;
return p;
}


int main() {
A a1;
a1.x = 1;
a1.s = "A\0";
printf("I'm an A: %s %d %p\n", a1.s, a1.x, &a1);

A a2 = stack_A("A\0",2);
printf("me too : %s %d %p\n", a2.s, a2.x, &a2);

A *p = &a1;
printf("me three: %s %d %p\n", p->s, p->x, p);

A *p2 = heap_A("A\0",3);
printf("me four : %s %d %p\n", p2->s, p2->x, p2);
return 0;
}