Как правильно инициализировать большую структуру с двусвязным списком? - PullRequest
1 голос
/ 13 июня 2019

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

$ gcc list.c -Wall
list.c: In function ‘newStudent’:
list.c:52:15: warning: variable ‘newNode’ set but not used [-Wunused-but-set-variable]
  studentList *newNode;
               ^~~~~~~
list.c: In function ‘initLists’:
list.c:36:14: warning: ‘auxSt’ is used uninitialized in this function [-Wuninitialized]
  auxSt->name = NULL;
              ^
list.c:41:14: warning: ‘auxR’ is used uninitialized in this function [-Wuninitialized]
  auxR->names = NULL;
              ^
list.c:46:16: warning: ‘school’ is used uninitialized in this function [-Wuninitialized]
  school->rooms = NULL;
                ^


Пока это мой код ...

typedef struct roomList roomList;
typedef struct school school;
typedef struct studentList studentList;

struct studentList
{

    char *name;
    int  grade;
    studentList *next;
    studentList *prev;
};

struct roomList
{   
    int class;
    int nrOfStudents;
    studentList *names;
    roomList *next;
    roomList *prev; 
};

struct school
{
    int totalStudents;
    roomList *rooms;
};

void initLists()
{
    studentList *auxSt;
    auxSt->name = NULL;
    auxSt->next = auxSt->prev = NULL;
    auxSt = NULL;

    roomList *auxR;
    auxR->names = NULL;
    auxR->next = auxR->prev = NULL;
    auxR = NULL;

    school *school;
    school->rooms = NULL;
    school = NULL;
}


int main()
{
    initLists();

     return 0;
}

Но, похоже, что после того, как я инициализирую свои вспомогательные переменные сначала с помощью NULL, прежде чем перейти к членам, это предупреждение исчезнет.Но у меня есть опасения по поводу инициализации вспомогательных переменных с NULL перед его собственными членами.Я на правильном пути для этого?

В чем преимущество использования функции init() перед инициализацией при вставке?Не видел почти ни одного примера онлайн с этой функцией.

Ответы [ 2 ]

2 голосов
/ 13 июня 2019

Давайте посмотрим на первую функцию.

studentList *newStudent(int class, char *name)
{
    studentList *newNode;
    newNode = (studentList*)malloc(sizeof(studentList));

    return NULL;     
}

Вы ничего не возвращаете. Ну, вы возвращаете нулевой указатель. Вся функция эквивалентна

studentList *newStudent(int class, char *name)
{
    return NULL;     
}

с единственным исключением, что ваш код вызывает дополнительную утечку памяти. Вам нужно заменить return NULL на return newNode. Кроме того, никогда не приводите malloc и используйте var вместо type в качестве аргумента для sizeof. Просто используйте newNode = malloc(sizeof(*newNode))

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

Я на правильном пути для этого?

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

0 голосов
/ 13 июня 2019
studentList *auxSt;  // auxSt is not initialized
auxSt->name = NULL;  // here you dereference a non initialized pointer

Конечно, вы получаете ‘auxSt’ is used uninitialized in this function предупреждение здесь, что вы ожидаете?

Теперь, я думаю, вы попробовали это:

studentList *auxSt = NULL;  // auxSt is initialized to NULL
auxSt->name = NULL;         // here you dereference an initialized pointer (no warning)

Здесь вы не получите ‘auxSt’ is used uninitialized in this function предупреждение, потому что здесь auxSt инициализировано . Однако этот код по-прежнему неверен, потому что разыменование NULL-указателя не закончится хорошо.

Так что в целом вы, вероятно, не на правильном пути.

Вся функция initLists полностью неверна.

...