0

The program is supposed to read the words of a file to a linked list. I got the Linked list working but now I'm faced with another error. I'm getting a segmentation fault when using a very large file.

It is working perfectly for smaller lists (3-10 words) but not for larger ones.

-----CODE-----
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node //struct for linked list
{
    char* word;
    struct node* next;
}
node;  

int main (void)
{        
    char* dictfile = "large";

    FILE* dict = fopen(dictfile, "r");

    if (dict == NULL)
        return 1;

    node* head = NULL;       

    char* oneword = malloc(sizeof(node));  //to store the word from fgets()

    while ((fscanf (dict, "%s", oneword)) > 0)
    {                                        
        node* temp = (node*)malloc(sizeof(node));

        char* tempword = (char*)malloc(sizeof(node)); //gives me a new pointer to store the string (as pointed out by Antione)

        strcpy(tempword, oneword);

        temp->word = tempword;

        printf("%s\n", temp->word);     //prints the value (just for debug)

        temp->next = head;            
        head = temp;             
    }

    node* temp = (node*)malloc(sizeof(node));
    temp = head;

    while(temp != NULL)    //loop to print the linked list
    {           
        printf("traverse %s\n", temp->word);    //prefix 'ing traverse to know its a linked list
        temp = temp->next;
    }

    free(head);
    free(temp);
    fclose(dict);

    printf("SUCCESS!!\n");      

}    

The result is as follows:

./tempeol
.............lots of words then the below
acceptor
acceptor's
tempeol: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
Aborted (core dumped)

Valgrind shows invalid writes at a few places.

One is where for the strcpy(). I have to account for the additional null character to resolve this but I don't know how.

    -----Valgrind Error-----
jharvard@appliance (~/Dropbox/pset5): valgrind ./tempeol
==4709== Memcheck, a memory error detector
==4709== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4709== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==4709== Command: ./tempeol
==4709== 
a
aaa
aaas
aachen
aalborg
==4709== Invalid write of size 1
==4709==    at 0x40DB401: _IO_vfscanf (vfscanf.c:1180)
==4709==    by 0x40E21F6: __isoc99_fscanf (isoc99_fscanf.c:34)
==4709==    by 0x8048681: main (tempeol.c:25)
==4709==  Address 0x423b1c0 is 0 bytes after a block of size 8 alloc'd
==4709==    at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4709==    by 0x8048662: main (tempeol.c:23)
==4709== 
==4709== Invalid read of size 1
==4709==    at 0x402D4F1: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4709==    by 0x80486D5: main (tempeol.c:31)
==4709==  Address 0x423b1c0 is 0 bytes after a block of size 8 alloc'd
==4709==    at 0x402A17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4709==    by 0x8048662: main (tempeol.c:23)
==4709== 
aalesund

Help needed!!

Also a funny thing: if I change char* tempword = (char*)malloc(sizeof(node)); to char* tempword = (char*)malloc(sizeof(node)*512); I end up getting the full linked list with a segmentation fault at the end.

I feel the solution lies in this line of code. Any ideas??

1 Answer 1

0

Found the solution to this error with the help from the users on stack exchange.

The problem was in the memory allocation of char* tempword and char* one word. The working code is as below for reference:

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node //struct for linked list
{
    char* word;
    struct node* next;
}
node;  

int main (void)
{        
    char* dictfile = "small";

    FILE* dict = fopen(dictfile, "r");

    if (dict == NULL)
        return 1;

    node* head = NULL;       

    char oneword[28];  //to store the word from fscanf()

    while ((fscanf (dict, "%s", oneword)) > 0)
    {                                        
        node* temp = (node*)malloc(sizeof(node));

        char* tempword = (char*)malloc(strlen(oneword)+1); //gives me a new pointer to store the string (as pointed out by Antione)

        strcpy(tempword, oneword);

        temp->word = tempword;

        //printf("%s\n", temp->word);     //prints the value (just for debug)

        temp->next = head;            
        head = temp;             
    }

    node* temp = head;

    while(temp != NULL)    //loop to print the linked list
    {           
        printf("%s\n", temp->word);    //prefix 'ing traverse to know its a linked list
        temp = temp->next;
    }

    printf("\n");

    free(head);
    //free(temp);   //no need for this (DrC)
    fclose(dict);

    printf("SUCCESS!!\n");      

}    

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .