Это объявление typedef
typedef struct node *Node;
сбивает с толку и представляет плохой стиль. Рассмотрим, к примеру, это утверждение
Node n = malloc(sizeof(*n));
, кто-то может подумать, что это опечатка и должно быть написано
Node *n = malloc(sizeof(*n));
Функция
void listInsertEnd(List newList, int value) {
Node n = newNode(value);
if (newList== NULL) { //no item in list
//why is this giving me memory leaks
newList->first = newList->last = n;
//whereas this doesn't?
newList->first = newList->last = newNode(value);
} else { //add to end
n->prev = newList->last;
newList->last->next = n;
newList->last = n;
}
nList->count++;
}
имеет неопределенное поведение. Если newList равен NULL, то вы пытаетесь использовать память, указанную нулевым указателем.
if (newList== NULL) { //no item in list
//why is this giving me memory leaks
newList->first = newList->last = n;
//whereas this doesn't?
newList->first = newList->last = newNode(value);
И первоначально элементы данных newList->first
и newList->last
могут быть равны NULL
. Это также может быть причиной неопределенного поведения, потому что функция не учитывает это.
Перед изменением функции listInsertEnd
вы должны определить функцию newNode
следующим образом
Node newNode(int value)
{
Node n = malloc(sizeof(*n));
if ( n != NULL )
{
n->value = value;
n->next = NULL;
n->prev = NULL;
}
return n;
}
Функция не должна выдавать никаких сообщений. Вызывающая функция решает, следует ли выдавать сообщение, если оно требуется.
В этом случае функцию listInsertEnd
можно записать следующим образом:
int listInsertEnd(List newList, int value)
{
Node n = newNode(value);
int success = n != NULL;
if ( success )
{
n->prev = newList->last;
if ( newList->first == NULL )
{
newList->first = newList->last = n;
}
else
{
newList->last = newList->last->next = n;
}
++newList->count;
}
return success;
}
В пределах main вы должны создать список следующим образом
int main( void )
{
struct list list1 = { .first = NULL, .last = NULL, .count = 0 };
// or
// struct list list1 = { NULL, NULL, 0 };
и вызвать функцию как
listInsertEnd) &list1, some_integer_value );