I'm working on a program that maintains a log file, and one of my tasks is to manage a linked list that stores the strings that I want to log. There is a function called clearlog that is meant to free the linked list (among another purpose which I haven't coded, yet).

The issue seems to be, however, that when I call free(), it doesn't seem to work...the pointer is still pointing to the information. I'm sure the fix is extremely simple, but I've been staring at this code for hours with no luck. Could one of you gurus help me?

loglib.c:
Code:
// Preprocessor Directives

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "log.h"

// Log Message (Linked List) Node Structure
typedef struct list_struct
{
        data_t item;
        struct list_struct * next;
} log_t;

// Declarations of variables to track the head and tail of
// the linked list.
static log_t * headptr = NULL;
static log_t * tailptr = NULL;

// This function creates a new node and appends it at the end of
// the message linked list.
int addmsg( data_t data )
{

        // Variable declaration
        log_t * newnode;
        int nodesize;

        // Allocation of space for new node and verification of action. 
        nodesize = sizeof( log_t ) + strlen( data.string ) + 1;
        if( ( newnode = ( log_t * )( malloc( nodesize ) ) ) == NULL )
                return -1; // Returns -1 if space wasn't successfully
                           // allocated.
        
        // Copying of data from data to newnode.
        newnode->item.time = data.time;
        newnode->item.string = ( char * )newnode + sizeof( log_t );
        strcpy( newnode->item.string, data.string );
        newnode->next = NULL;

        // Placement of newnode in the linked list.
        if( headptr == NULL )
                headptr = newnode;
        else
                tailptr->next = newnode;
        tailptr = newnode;

        // Returns zero if function was successful.
        return 0;
}

void clearlog( void )
{
        log_t * cnode;
        log_t * nnode;
        char * s;

        cnode = headptr;

        while( cnode != NULL ) 
        {
                nnode = cnode;
                cnode = cnode->next;
                free( nnode );
                if( nnode != NULL ) 
                        perror( "Memory failed to be freed\n" );
        }

        tailptr = headptr;
        
}

void test_me( void )
{
        printf ("%s", headptr->item.string);
        return;
}
log.h
Code:
#include <time.h>

typedef struct data_struct
{
        time_t time;
        char * string;
} data_t;

int addmsg( data_t data );
void clearlog( void );
void test_me( void );
driver.c
Code:
#include <stdio.h>
#include "log.h"

int main( int argc, char * argv[] )
{
        data_t test;
        int return_value;

        test.time = time( NULL );
        test.string = "This is only a test!\n";


        if( ( return_value = addmsg( test ) ) == -1 )
        {
                perror( strcpy( argv[0], ": Error: Memory Allocation Failed!" ) );      
                return -1;
        }

        test_me();

        clearlog();

        test_me();

        return 0;
}
Output:
This is only a test!
Memory failed to be freed
: Error 0
Does anyone know what I'm doing wrong, or possibly any other causes for why free() doesn't free the allocated memory?

I really appreciate this!