Простая проблема указателя в C - неправильное значение - PullRequest
1 голос
/ 20 марта 2011

Я работал над чем-то простым, используя связанные списки, и я понял, что есть кое-что, чего я не понял.Я не могу понять, почему программа ниже не печатает 3 (она печатает случайное число).Я думаю, это также странно, что я не получаю ошибок во время выполнения, и у не 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);
}

Ответы [ 6 ]

4 голосов
/ 20 марта 2011

Вы передаете значение str x функции do_something.

Изменение x в do_something не изменит y в функции main. Либо передайте ссылку на y следующим образом:

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

или заставить функцию do_something вернуть адрес распределенной структуры:

Ниже приведен обычный способ сделать это в 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);
}
2 голосов
/ 20 марта 2011

Вот что вы хотите сделать:

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

В противном случае копия переданного указателя будет установлена ​​на желаемое значение

1 голос
/ 20 марта 2011

x = p; назначает расположение выделенной памяти для локальной переменной x, которая быстро забывается. Либо вернуть адрес выделенной структуры, например:

str* do_something() {
    str *p = (str *)malloc (sizeof (str));
    p->y = 3;
    return p;
}
int main() {
    str * y = do_something();
    printf("%d", y->y);
}

Или указать адрес do_something можно написать адрес [sic] по адресу:

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);
}
1 голос
/ 20 марта 2011

Так как C - это , передаваемое по значению , y сохраняет обратный указатель на некоторый мусор, состояние которого было в main()Чтобы действительно сделать то, что вы хотели, do_something(..) должен возвращать ссылку типа str *.

str* do_something(str *x)
{
    str *p = (str *)malloc (sizeof (str));
    p->y = 3;
    x = p;
    return x ;
}

// И возвращаемое значение нужно собрать.

str *y;  // It's a good practice to set y to NULL. Do this instead. str *y = NULL ;
y = do_something (y);
1 голос
/ 20 марта 2011

чтобы изменить y, вам нужно отправить & y, поэтому параметр do_something на самом деле должен быть 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);
}
0 голосов
/ 20 марта 2011

Попробуйте программу ниже.Ваша программа нуждается в некоторой коррекции.

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...