C - передача по значению, а не передача по ссылке.Таким образом, List* list
в функции list_add
и List* list
в main
относятся к двум разным местам в памяти (они изначально указывают на одно и то же место в начале list_add
, но они являются двумя разными указателямиизначально с одним и тем же значением, а не с тем же указателем): изменение значения переменной list
в пределах list_add
не влияет на значение list
в main
.
Конкретно:
list = &n1
в list_add
изменяет только значение list
внутри этой функции, то есть значение аргумента, которое было скопировано в кадр стека list_add
при вызове.Однако, когда вы пытаетесь напечатать его в строке 59, все еще в пределах list_add
, измененное значение будет видно и, таким образом, будет напечатан указатель, работая, как вы ожидаете.
Когда вы пытаетесь напечатать list
в строке 39 в main
, с другой стороны, переменная list
в функции main
не изменила свое значение с помощью присваивания list = &n1
непосредственно перед строкой 39 в list_add
, поскольку она изменилась толькозначение копии в области действия этой функции.Таким образом, в этом случае list_print
пытается распечатать элементы пустого списка (поскольку значение list
все еще является только тем, что было возвращено list_create
, который является указателем на указатель NULL
, и поэтому Elem aux = **list
таким образом разыменовывает list
, а затем пытается разыменовать указатель NULL
) и, таким образом, приводит к недопустимому доступу к памяти.
В этом коде проблема не в размещении печати списка, а в том, чтоlist_add
не обновляет список должным образом.Исправляя это, вы должны принять во внимание, что он может изменять структуру списка, только изменяя то, на что указывает ссылочное значение, полученное в качестве аргумента, а не пытаясь изменить сам указатель.Если вы хотите изменить адрес, на который указывает list
в main
из функции list_add
(например, то, что, по-видимому, пытается сделать строка list = &n1
), вам нужно будет передать указатель на list
в list_add
, а не просто указатель list
.
В самом коде, похоже, есть другие проблемы (list_print
печатает только один элемент и не обрабатывает печать пустых списков,например, именно это приводит к тому, что ошибка в данном случае является фактическим неверным доступом к памяти, а не просто неправильно оставляет список пустым после вызова list_add
), но проблема, описанная выше, является причиной этой конкретной проблемы.