Simple pointer problem in C - wrong value
I was working on something simple, using linked lists and I realized there is something I didn't understand. I can't figure out why the program below doesn't print 3 (it prints a random number). I think it's also weird that 开发者_如何学运维I get no errors at runtime and y is not NULL.
struct ceva
{
int y;
};
typedef struct ceva str;
void do_something(str *x)
{
str *p = (str *)malloc (sizeof (str));
p->y = 3;
x = p;
}
int main(void)
{
str *y;
do_something (y);
printf ("%d", y->y);
}
You're passing by value the str x
to the function do_something
.
Changing x
in do_something
will not change y
in the main
function. Either pass a reference to y
in as follows:
void do_something(str **x)
{
str *p = (str *)malloc (sizeof (str));
p->y = 3;
*x = p;
}
int main(void)
{
str *y;
do_something (&y);
printf ("%d", y->y);
}
or make the function do_something
return the address of the structure it allocated:
The following is the usual way of doing this in C.
str *do_something(void)
{
str *p = (str *)malloc (sizeof (str));
if (p) // ensure valid pointer from malloc.
{
p->y = 3;
}
return p;
}
int main(void)
{
str *y = do_something (y);
printf ("%d", y->y);
}
Here's what you want to do:
void do_something(str **x)
{
str *p = (str *)malloc (sizeof (str));
p->y = 3;
*x = p;
}
int main(void)
{
str *y;
do_something (&y);
printf ("%d", y->y);
}
Otherwise the copy of the passed pointer will be set to your desired value
in order to change y, you need to send &y, so do_something parameter will actually need to be str **x
struct ceva{
int y;
};
typedef struct ceva str;
void do_something(str **x)
{
str *p = (str *)malloc (sizeof (str));
p->y = 3;
*x = p;
}
int main(void)
{
str *y;
do_something (&y);
printf ("%d", y->y);
}
Since, C
is pass by value, y
is retaining back pointing to some garbage, which it's state was in main()
. To actually do what you intended, do_something(..)
should return a reference of type str*.
str* do_something(str *x)
{
str *p = (str *)malloc (sizeof (str));
p->y = 3;
x = p;
return x ;
}
// And the returned value needs to be collected.
str *y; // It's a good practice to set y to NULL. Do this instead. str *y = NULL ;
y = do_something (y);
x = p;
assigns the location of the allocated memory to the local variable x
which is promptly forgotten. Either return the address of the allocated struct, like:
str* do_something() {
str *p = (str *)malloc (sizeof (str));
p->y = 3;
return p;
}
int main() {
str * y = do_something();
printf("%d", y->y);
}
Or supply an address do_something
can write an address[sic] to:
void do_something(str** x) {
str *p = (str *)malloc (sizeof (str));
p->y = 3;
*x = p;
}
int main() {
str* y;
do_something(&y);
printf("%d", y->y);
}
Try out the program below. Your program needs some correction.
struct ceva
{
int y;
};
typedef struct ceva str;
ceva* do_something()
{
str *p = (str *)malloc (sizeof (str));
p->y = 3;
return p;
}
int main(void)
{
str *y = (str *)malloc (sizeof (str));;
y->y = 2;
y = do_something ();
printf ("%d", y->y);
}
精彩评论