tags:

views:

153

answers:

4

I'm wondering what's the difference between sample1 and sample2. Why sometimes I have to pass the struct as an argument and sometimes I can do it without passing it in the function? and how would it be if samplex function needs several structs to work with? would you pass several structs as an argument?

struct x
{
    int  a;
    int  b;
    char *c;
};

void sample1(struct x **z;){
    printf(" first member is %d \n", z[0]->a);
}

void sample2(){
    struct x **z;
    printf(" first member is %d \n", z[0]->a); // seg fault
}

int main(void)
{
    struct x **z;

    sample1(z);
    sample2();

    return 0;
}
+1  A: 

First of all, your argument type is not struct, but a pointer to pointer to struct (or an array of pointers to struct - these are semantically equivalent from the callee's point of view, except that the address of an array can't be changed).

In the second case you use a local variable that is totally independent of the one with same name in main. Since it is not initialized, you get a seg fault when trying to access one of its members. (The one in main is not initialized either, but accessing it just seems to work by chance in sample1).

You should initialize your variables before using them, otherwise you enter the territory of undefined behaviour. E.g.

void sample1(struct x **z){
    printf(" first member is %d \n", z[0]->a);
}

void sample2(){
    struct x z[1];
    z[0].a = 1;
    ...
    printf(" first member is %d \n", z[0].a);
}

int main(void)
{
    struct x z[1];

    z[0].a = 1;
    ...
    sample1(z);
    sample2();

    return 0;
}
Péter Török
A: 

Both are invalid and accessing bad memory. The results are undefined so both results are correct.

Brian R. Bondy
A: 

C and C-like languages have a concept of "scope". See all those curly braces ({ and })? Those are "blocks". They essentially wrap all the code between them into bundles that are independent of any other blocks at the same level. Any variable you create in that block is only accessible within that block—you can't reference it anywhere else.

You can create a nested block. For example:

int f() {
    int x;
    scanf("%d", &x);
    if (x == 3) {
        return 7;
    }
    else {
        return x;
    }
}

As you can see, the else block is nested inside the function's block, and so can access the function's variables.

When you declare struct x **z in both main and sample2, you're actually creating two variables, both called z. These are totally independent—they're not the same variable at all. They're not related. The only thing they have in common is their name and type—the actual value is different. The only way you can use the same variable in both is by passing, as you do in sample1.

Of course, currently, your z pointer is garbage—you haven't allocated anything. I'd recommend you actually store something in there before you try and dereference it.

Samir Talwar
A: 

Your declaration

struct x **z;

simply creates a pointer to a pointer to a structure of type x. You're not actually initialising the pointers, i.e. making them point anywhere.

Try something like

struct x z;
struct x *pZ = &z;

sample1(&pZ);

(I'm not completely sure what you're actually trying to achieve, though!)

Vicky