Как правильно изменить указатель внутри структуры в функции? Я делаю это неправильно Как это сделать? - PullRequest
0 голосов
/ 03 ноября 2019

У меня есть struct, я определил ее как node1, теперь в функции main() создано 3 указателя на узел node1 node2, которые являются указателями на тип node1 (который является структурным узлом, который я создал).

Inэтот первый фрагмент кода, который я получил, вывел

3
9
2

Это означает, что когда я изменяю node->next внутри функции, он сам не отражается в основной функции, он работает только внутри функции, хотя я здесьиспользуется вызов по ссылке (следующий фрагмент кода)

Я делаю это неправильно?

Код

#include <stdio.h>
#include <stdlib.h>
struct Node {
  int data;
  struct Node *next;
};
void func(struct Node* node) {
  node->data = 9;
  node->next = (node->next)->next;
  printf("%d\n", (node->next)->data);
}

int main() {
  struct Node *node0, *node1, *node2;

  node0 = (struct Node *)malloc(sizeof(struct Node));
  node1 = (struct Node *)malloc(sizeof(struct Node));
  node2 = (struct Node *)malloc(sizeof(struct Node));
  node0->data = 1;
  node0->next = node1;
  node1->data = 2;
  node1->next = node2;
  node2->data = 3;
  node2->next = NULL;

  func(node0);
  printf("%d\n%d", node0->data, node1->data);
}

Теперь это код, которыйя написал сначала с вызовом по ссылке, это ne также дает тот же вывод

мой желаемый вывод

3
9
3

Так что даже при вызове по ссылке его не работаетКакое решение для этого?

#include <stdio.h>
#include <stdlib.h>
struct Node {
  int data;
  struct Node *next;
};

void func(struct Node **node) {
  (*node)->data = 9;
  ((*node)->next) = (((*node)->next)->next);
  printf("%d\n", ((*node)->next)->data);
}

int main() {
  struct Node *node0, *node1, *node2;

  node0 = (struct Node *)malloc(sizeof(struct Node));
  node1 = (struct Node *)malloc(sizeof(struct Node));
  node2 = (struct Node *)malloc(sizeof(struct Node));
  node0->data = 1;
  node0->next = node1;
  node1->data = 2;
  node1->next = node2;
  node2->data = 3;
  node2->next = NULL;

  func(&node0);
  printf("%d\n%d", node0->data, node1->data);
}

Как правильно сделать это?

Я хочу, чтобы решение изменило указатель внутри структуры без возврата и переназначения.

Так вот что я хочу. После вызова функции я хочу, чтобы переменная node1 указывала на точное местоположение как node2.

1 Ответ

0 голосов
/ 03 ноября 2019

Таким образом, в func вы только изменяете (меняете) узел, в котором проходите, node0. Перед вызовом func это выглядит следующим образом: node0->node1->node2->NULL, затем в func вы изменяете поле data узла, в котором вы прошли, node0.

После этого вы изменяете поле next, снова на node0, чтобы указать на node2, node0->next = node1, поэтому (node0->next)->next = node2.

Теперь это выглядит так node0->node2->NULL и node1->node2->NULL, вы ничего не изменили в node1 или node2.

Затем вы печатаете (node->next)->data с node, все еще равным node0, поэтому вы печатаете 3.

Затем после возврата из функции, которую вы печатаете node0->data и node1->data, помните, что вы не изменили node1 или node2 в func. Таким образом, результат - это то, что мы должны ожидать.

Если я правильно понимаю ваш вопрос, вы хотите, чтобы переменная node1 указывала на ту же память, на которую указывает node2после звонка на func. Это не может быть сделано изнутри func, поскольку node0->next является просто копией адреса node1. Вы изменяете эту копию, но func не имеет доступа к переменной node1 и поэтому не может ее изменить. Даже если бы вы могли, это привело бы к утечке памяти, поскольку у вас не было бы способа вызвать free на node1.

В качестве примечания, вы должны избегать приведения возврата из malloc, см. F. ех. этот вопрос .

...