Это невозможно без динамического c распределения. Если вы не хотите использовать malloc
, вы можете использовать свою собственную реализацию области распределения.
Но вы не можете использовать висячие указатели, что и делает ваша реализация.
void insertAtStart(sll** head, int data)
{
sll newNode = { data, NULL };
newNode
- это переменная со сроком хранения automati c, что означает, что она существует только до тех пор, пока функция, в которой она объявлена, не вернется (или не будет завершена иным образом).
newNode.data = data;
if (*head == NULL)
{
*head = &newNode;
Итак, теперь *head
указывает на объект с автоматической c продолжительностью хранения. Но посмотрите, что происходит дальше:
return;
Как только этот return
выполняется, insertAtStart
завершается, и время жизни всех его локальных переменных, включая newNode
, внезапно заканчивается. И когда время жизни объекта заканчивается, так же как и удобство использования указателя на этот объект. чтобы обеспечить их соблюдение. Все просто загадочным образом терпят неудачу.
Сказать, что время жизни объекта закончилось, не означает, что память, в которой этот объект хранился, перестает существовать. На вашем компьютере нет маленьких нанороботов, которые могут создавать и разбирать физическую память. Это означает, что память больше не содержит этот объект и может (будет) использоваться повторно для других целей.
Аналогично, хотя стандарт C ясно, что указатель на завершенный объект перестает быть быть пригодным для использования («Значение указателя становится неопределенным, когда объект, на который он указывает… достигает конца своего жизненного цикла»), ничто на самом деле не мешает вам попытаться использовать указатель; проблема в том, что он может указывать на другой объект, расположенный в той же памяти. И вот что здесь происходит: в результате ваш связанный список становится круговым списком мусора.