开发者

Simple pointer problem in C - wrong value

开发者 https://www.devze.com 2023-02-18 17:05 出处:网络
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

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);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消