void add_to_list(struct list *l, int newval)
Ваша функция объявлена как void
. Это означает, что для функции ваша функция сигнализирует об ошибке. Не проблема для кода примера, , но определенно то, о чем вы должны хотя бы знать.
if (!l) return; //my fried said that I should add this,
//and should it be if(l == NULL) rather than if(!l)?
Конструкция (!l)
полностью эквивалентна (l != NULL)
. Это происходит потому, что NULL
определяется как «пустого указатель постоянной», и «пустого указателя постоянной» является «Константой выражения целого с значения 0, или такое выражение приводится к типу void *
» , В других словах NULL
оценивает на ноль.
while(l->next !=NULL) // I am pretty sure that this while loop is correct
l=l->next;
Да, это while
петля правильно. Когда цикл завершается, l
будет указывать на последний элемент в списке.
l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory
Ваше распределение почти справа. Вы выделяете достаточное количество хранилища для , удерживая один int
, но вам действительно нужно достаточно места для хранения struct list
. вместо этого используйте l->next = malloc(sizeof(struct list));
.
l->next->val = newval; //not sure about this
Ошибка здесь. Это точно так же правильно, как и следующая строка.
l->next->next = NULL; //This should be fine
Да, это нормально ..
Однако, в то время как эта часть кода в основном правильно, запрещая malloc()
, что уже была покрыта,
l->next = malloc(sizeof(int)) //hmm... is this correct way to allocate memory
l->next->val = newval; //not sure about this
l->next->next = NULL; //This should be fine
метод, используемый здесь немного необычно. Это связано с тем, что при назначении новой памяти вы назначаете указатель непосредственно на l->next
и затем инициализируете его.
Что чаще делается это todeclare указателя, такие как struct list *tmp = NULL
в начале функции, и при выделении, назначить новую память tmp
. Затем, , инициализируйте новый элемент списка, на который указывает tmp
, и , затем добавьте новый элемент списка с новым именем в конец списка . Хотя это включает в себя несколько больше кода, разделяет два шага создания нового элемента списка и добавления элемента в конец списка.
void add_to_list(struct list *l, int newval)
{
struct list *tmp = NULL;
if (!l) return; // If no valid list, return.
tmp = malloc(sizeof(struct list)); // Allocate new list element
tmp->val = newval; // and fill it up.
tmp->next = NULL; // End of the list always points nowhere.
while(l->next !=NULL) // find end of list.
l=l->next;
l->next = tmp; // Attach new list element to end.
return;
}
Кроме того, делая это таким образом избежать возможной путаницы, которая может возникнуть от присвоения значений через l->next
указатель.
'l-> next = malloc (sizeof (int))' Это действительно правильный способ выделения памяти, но вы не выделяете достаточно. Вам нужно выделить достаточно, чтобы содержать весь 'struct list'. Измените эту строку на 'l-> next = malloc (sizeof (* (l-> next)))' –