Hello! I need help with the sheets, there is such a code, I wrote it myself for practice, but I don’t understand where the trouble is, explain, pliz.

#include <stdlib.h> #include <stdio.h> #include <malloc.h> typedef struct node { int num; struct node *next; struct node *Prev; } Node; Node *init() { int i; Node *ptr = (Node*)calloc(10, sizeof(Node)); for (i = 1; i <= 10; i++, ptr->next) { ptr->num = 1; ptr->next = NULL; } } int main() { Node *head; head = 0; head->num = 1; head->next = NULL; head->Prev = NULL; return 0; } 
  • @nwhta, Try to write more detailed questions. Explain what you see the problem, how to reproduce it, etc. - Nicolas Chabanovsky

2 answers 2

What did you want to get?

Here is:

  head->num = 1; 

in main , this is an obvious mistake, since you yourself write a line earlier:

 head = 0; 

and the 0-th (aka NULL) address can not be accessed.

Update

@smackmychi , this is obviously the case. So let's try (if, of course, he does not run away) quickly push him in the right direction.

@nwhta , judging by the structure of the Node, you want to make a doubly linked list. Perhaps from 10 elements, numbered from 1 to 10.

This is true?

And one more question, have you already read about memory, addresses and pointers?

Update 2

@nwhta , (without any raids) why allocate memory for 10 structures, and even in a function that is not called?

It seems to me that it is more logical to allocate memory for one structure in it, enter the element number in it and return.

Those. main will be the following cycle:

  for (i = 1; i < 11; i++) { Node *item = init_item(i); // а здесь будем вставлять в список } 

By the way, it is better to organize a doubly linked list in the form of 2 pointers, one to the first and the other to the last elements of the list.

Update 3

@nwhta , if the pointers to the beginning and end of a doubly linked list are initialized with zeros, then adding a new element to the end of the list is done like this:

  // порядок строк кода важен !!! item->next = 0; if (!head) head = item; else tail->next = item; item->prev = tail; tail = item; 

After that the list is in a consistent state and it can, for example, be printed in direct

  for (item = head; item; item = item->next) printf("%d\n", item->num); 

and reverse

  for (item = tail; item; item = item->prev) printf("%d\n", item->num); 

okay

I hope you do the rest.

Update 4

The general code for adding an element is, of course, good, but in practice it is often more efficient to solve particular problems, generalizing these solutions to an acceptable level.

For example, in our insertion code it is constantly checked whether the list is not empty? Obviously, if we have a task to make a list of known length, then it is absolutely ugly.

Let's try to write a generalized solution of a particular problem - to make a list of consecutive numbers of N elements in size.

To begin with, we will write a function that returns a filled list item.

 #include <sysexits.h> static inline struct node *make_item(int num) { struct node *p = (typeof(p))calloc(1, sizeof(*p)); if (!p) { perror("allocate node"); exit(EX_OSERR); // корректный для такой ситуации код завершения из sysexits.h } p->num = num; return p; } 

Pay attention, just in case (possible changes in the future) use calloc() , i.e. immediately reset the pointers to the previous and next list items.

Since the function is very small, let's ask the compiler not to call it (call), but to embed its code everywhere in the code of the calling function (this speeds up execution) and for this we assign it the words static inline (more in textbooks).

Here we make a design decision - if the OS cannot allocate memory - let the user know about it and complete the program . Such a solution is not indisputable, but in most cases it suits everyone completely, and the programmer’s life (error analysis) makes it much easier.

Now we recall that the list (by the way, any non-cyclic, which is double, that simply connected) is convenient to represent a pair of pointers. For convenience, combine them into the structure:

  struct list2 { struct node *head, *tail; }; 

And here everything is ready for writing the function, which generally solves our private task.

 // Returns list (struct of 2 pointers) // строит двусвязный список последовательных чисел размером n элементов, // начиная с числа first_num struct list2 make_nlist (int first_num, int n) { /* инициализируем структуру для разумного результата при ошибке в запрашиваемом размере списка */ struct list2 list = {0, 0}; if (n-- > 0) { // запрошен непустой список // вставим первый элемент, поэтому в if уменьшали n list.head = list.tail = make_item(first_num++); while (n--) { // вставим в хвост списка все остальные list.tail->next = make_item(first_num++); list.tail->next->prev = list.tail; list.tail = list.tail->next; } } return list; } 

Now you can use this function, for example, to print sequences of numbers starting with 1 "forward and back" :)

 int main (int ac, char *av[]) { struct node *item; struct list2 list = make_nlist(1, atoi(av[1] ? av[1] : "10")); for (item = list.head; item; item = item->next) printf("%d\n", item->num); puts ("=="); for (item = list.tail; item; item = item->prev) printf("%d\n", item->num); return puts("End") == EOF; } 
  • @avp I'm afraid, this is exactly the question when a person uses tools that he really doesn't know anything about. - smackmychi
  • Yes, it seems like yes ... - nwhta
  • @nwhta, updated the answer. I hope now figure it out. - avp
  • @nwhta, wrote another update. If something interested in programming - ask. - avp

head = 0 - this is right, the variable should be initialized.
The second part is missing head = new Node; . If I am mistaken, correct me.

  • @ulcigor, this is pure C, there are no classes and new. - etki
  • Well, you can do it through malloc. - ulcigor
  • Can you show with an example how best? - nwhta