link pointer access problem

V

vichy.kuo

Dear all:
Below is my program:
#include<stdio.h>
typedef struct{
int b_value;
}B;

typedef struct{
B* next;
int a_value;
}A;

int main(void)
{
A a;
//B* pb;
a.a_value=12;
//pb=a.next;
//pb->b_value=23;
a.next->b_value=23;

printf("b_value=%dvn",a.next->b_value);
//printf("b_value=%dvn",pb->b_value);
return 0;
}

The program will get segment fault or compiler will say "request for
member 'b_value' in something not a structure or union".

The program will be fine if I unmark "//" part, which is the way that
people usually to access link list.

"next" is an element of A, so a.next should be fine.
"a.next" is a pointer which point to B, so a.next->b_value seems ok.
Do my assumption correct?
Sincerely Yours,
vichy
 
B

Ben Bacarisse

#include<stdio.h>
typedef struct{
int b_value;
}B;

typedef struct{
B* next;
int a_value;
}A;

int main(void)
{
A a;
//B* pb;
a.a_value=12;
//pb=a.next;
//pb->b_value=23;
a.next->b_value=23;

printf("b_value=%dvn",a.next->b_value);
//printf("b_value=%dvn",pb->b_value);
return 0;
}

The program will get segment fault or compiler will say "request for
member 'b_value' in something not a structure or union".

I am pretty sure that that compiler message comes from some other
program that you have not shown us.
The program will be fine if I unmark "//" part, which is the way that
people usually to access link list.

No, both versions (the commented one and the one with //'s remove) are
essentially the same. The are both "undefined" -- they have an error
that means that anything can happen. If they behave differently, that
is also permitted.
"next" is an element of A, so a.next should be fine.

Indeed it is...
"a.next" is a pointer which point to B, so a.next->b_value seems ok.

Syntactically, yes. The trouble is that a.next has not been set. It
is a pointer object but you don't know where it points. Just as it
would be wrong to use a.a_value unless you had set it to 12, it is
wrong to use a.next without setting it.

To set it, there must be an object of type B somewhere that it can
point at. Perhaps you intended to declare a B and set it like this:

B b;
a.next = &b;

<snip>
 
J

jameskuyper

Dear all:
Below is my program:
#include<stdio.h>
typedef struct{
int b_value;
}B;

typedef struct{
B* next;
int a_value;
}A;

int main(void)
{
A a;

At this point, a is uninitialized; all of it's members have
indeterminate values. That means, in particular, that a.next may have
a trap representation.
//B* pb;
a.a_value=12;
//pb=a.next;
//pb->b_value=23;

You don't have any objects of type B in your program, and you have not
set a.next to point to any such object. You haven't even set a.next to
be a null pointer (though that would not help, in this case). At this
point, a.next still has an indeterminate value. Therefore, the
behavior of the next statement is undefined:
a.next->b_value=23;

The same is true of this statement, for the same reason:
printf("b_value=%dvn",a.next->b_value);
//printf("b_value=%dvn",pb->b_value);
return 0;
}

The program will get segment fault or

That is an entirely reasonable and plausible result from attempting to
dereference a pointer with an indeterminate value.
... compiler will say "request for
member 'b_value' in something not a structure or union".

However, I see no justification for such a message. A smart compiler
could have recognized at compile time that your code dereferences an
uninitialized pointer; but if so, this message seems like a very odd
way to describe that fact.
The program will be fine if I unmark "//" part, which is the way that
people usually to access link list.

It will not be fine. Even simply copying the value of a.next to pb has
undefined behavior, if a.next contains a trap representation. If
a.next doesn't contain a trap representation, it's indeterminate value
will be copied to pb, with no guarantee that it points at any location
that can be safely dereference. However, since the behavior is
undefined, one of the possible results is that, this time, the
uninitialized value of a.next happens to point at memory that you can
safely read and write to.
"next" is an element of A, so a.next should be fine.
"a.next" is a pointer which point to B,
Correct.

... so a.next->b_value seems ok.

Not until a.next has been given a value that points at an actual B
object.
 
D

David RF

Dear all:
Below is my program:
#include<stdio.h>
typedef struct{
        int b_value;

}B;

typedef struct{
        B* next;
        int a_value;

}A;

int main(void)
{
        A a;
        //B* pb;
        a.a_value=12;
        //pb=a.next;
        //pb->b_value=23;
        a.next->b_value=23;

        printf("b_value=%dvn",a.next->b_value);
        //printf("b_value=%dvn",pb->b_value);
        return 0;

}

The program will get segment fault or compiler will say "request for
member 'b_value' in something not a structure or union".

a.next is not initialized, pb points to garbage in this line
pb=a.next;
"next" is an element of A, so a.next should be fine.
"a.next" is a pointer which point to B, so a.next->b_value seems ok.
Do my assumption correct?
Sincerely Yours,

Yes
 
V

vichy.kuo

Hi:
thanks for your kind help.
a.next is not initialized, pb points to garbage in this line
pb=a.next;


Yes
as your kind explanation, I make a mistake that a.next is not assigned
properly :p
Sincerely Yours,
vichy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,816
Messages
2,569,714
Members
45,502
Latest member
Andres34P

Latest Threads

Top