Я могу изменить член структуры из одного места, но не из другого - PullRequest
0 голосов
/ 19 сентября 2018

Я пытаюсь реализовать связанный список в C - начиная с простого, с одним списком, содержащим один узел.Однако я сталкиваюсь с некоторыми проблемами при попытке добавить данные в узел.Вот моя реализация до сих пор:

struct mylist_node {
  int data;
};

struct mylist {
  struct mylist_node *head_pt;
};

void mylist_init(struct mylist* l){
    struct mylist_node head_node;
    head_node.data = 5; //First try
    l->head_pt = &head_node;
    l->head_pt->data = 5; //Second try
};

И мой основной метод:

int main()
{
    struct mylist ml, *ml_pointer;
    ml_pointer = &ml;
    mylist_init(ml_pointer);

    printf("%d\n", ml_pointer->head_pt->data);
    ml_pointer->head_pt->data = 4;
    printf("%d\n", ml_pointer->head_pt->data);

    return 0;
}

Это должно распечатать

5
4

Если мои знания указателей верны.Тем не менее, он выводит

0
4

Как вы можете видеть, я пытаюсь установить данные узла дважды в методе mylist_init.Ни один из них, похоже, не работает - в то же время, запись в него и чтение из него из моего основного метода работает просто отлично.Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

Для начала, вы должны выделить память для вашего узла, как вы это делали, ваш узел является локальной переменной в стеке, которая, вероятно, будет перезаписана после выхода из функции.

void mylist_init(struct mylist* l)
{
    struct mylist_node *head_node = (struct mylist_node *)malloc(sizeof(struct mylist_node));
    head_node.data = 5; //First try
    l->head_pt = head_node;
};
0 голосов
/ 19 сентября 2018

В mylist_init вы храните адрес локальной переменной в структуре, на которую указывает l.Эта переменная выходит из области видимости, когда функция возвращается, поэтому занимаемая ею память больше не является допустимой, и, таким образом, указатель, который ранее указывал на нее, теперь указывает на недопустимое расположение.Возвращая адрес локальной переменной, разыменование этого адреса вызывает неопределенное поведение.

Ваша функция должна динамически распределять память, используя malloc, поэтому память все равно будет действительной, когда функция вернется.

void mylist_init(struct mylist* l){
    struct mylist_node *head_node = malloc(sizeof(*head_node));
    l->head_pt = head_node;
    l->head_pt->data = 5; 
};

Кроме того, не забудьте free память, когда вы закончите, используя ее.

...