Используемый вами подход неверен.
В список следует добавлять данные, а не указатели на узлы.
Функции можно определить следующим образом.
node_t * create_new_node( char *card )
{
node_t *result = malloc( sizeof( node_t ) );
if ( result != NULL )
{
result->card = card;
result->next = NULL;
}
return result;
}
Эти две функции будут проще и менее подвержены ошибкам, если передать указатель на головной узел по ссылке.
int insert_at_head( node_t **head, char *card )
{
node_t *node_to_insert = create_new_node( card );
int success = node_to_insert != NULL;
if ( success )
{
node_to_insert->next = *head;
*head = node_to_insert;
}
return success;
}
// add new node at the end of the list
int add_node( node_t **head, char *card )
{
while ( *head != NULL )
{
head = &( *head )->next;
}
*head = create_new_node( card );
return *head != NULL;
}
И в основном вы можете написать
char *card_list[] =
{
"counterspell", "black lotus", "giant growth", "mountain", "forest"
};
size_t len = sizeof( card_list ) / sizeof( card_list[0] );
node_t *head = NULL;
for ( size_t i = 0; i < len; i++ )
{
add_node( &head, card_list[i] );
}
Обратите внимание на то, что в целом вы должны делать копию переданной строки в каждом узле.