Thread: Segmentation fault problem

  1. #1
    Registered User
    Join Date
    Apr 2012
    Posts
    9

    Segmentation fault problem

    Good day everyone.

    I just want to know if I'm doing everything right in 2 of my functions. First off, the function inserttolist just connects the node created by parse_file. The linked list contains parts of a file, which I send to another PC. I didn't put this into the networking section because I think that the networking part of my code is already working.

    There are two problems that I encounter when using these functions. First, when I try to allocate a small memory size for my chunksize(say 100bytes), a segmentation fault usually happens.

    Another problem that I encounter is when I try to traverse the list, a segmentation fault SOMETIMES happen. If for example, I traversed it in one go(meaning, traverse the first node until the last), it runs fine. But when I traverse it when I need to resend a part of the file which is lost(since this is used in a file transfer program), it sometimes encounter a segmentation fault.

    For the linked list:
    Code:
    struct flist{                //linked list for file chunk       
            char *chunk;            //file segment
            int chunksize;            //size of chunk of this node
            int isn;            //segment number of packet
            int res;
            int last;
            int acked;
            struct flist *next;        //pointer to the next node
        };
        typedef struct flist Flist;    
        Flist *fileparse = NULL;        //define pointer of struct flist
    For the parse_file:
    Code:
    void parse_file(Flist* sPtr, int chunksize, int isn, char filename[]){                
        FILE *ptr;                //file pointer
        char *buffer1, *buffer2;                //pointer to memory holding each chunk
        int quotient;                //counter for f
        int modulo;
        size_t res;                //for fread
        int counter = 0;                //just a counter
        
        /*open file*/
        if ((ptr = fopen(filename, "r+b")) == NULL)            //if file cannot be opened..
        {
            printf("File open error\n");
            goto end;
        }
        else{
        /*obtain file size*/
        fseek (ptr , 0 , SEEK_END);
          filesize = ftell (ptr);
         rewind (ptr);
        }
        /*obtain number of chunks to be made*/
        if(filesize<chunksize){
            printf("File size is too small for chunk\n");
            quotient = 0;
            modulo = filesize;
            goto start;
        }
        quotient = filesize/chunksize;
        modulo = filesize%chunksize;
            printf("Modulo is %i\n",modulo);
    
        start:
        buffer1 = (char *)malloc(sizeof(char)*chunksize);        //allocate memory for chunk
        buffer2 = (char *)malloc(sizeof(char)*modulo);        //allocate memory for chunk
        /*start getting the chunks*/
        while(1){
            if(counter!=quotient){
                memset(buffer1,0,chunksize);
                if(buffer1 == NULL){
                    printf("Allocation failed\n");
                    goto end;
                }
                res = fread(buffer1,sizeof(char),chunksize,ptr);    //get the chunk from file pointer
                  if (res != chunksize){
                    goto end;
                }
                inserttolist(sPtr,res,isn,buffer1,0,res,modulo);
                counter++;                        //increment counter
                isn = isn + res;                            //increment segment number
                
            }
            else if((counter == quotient) && (modulo != 0)){
                memset(buffer2,0,modulo);
                if(buffer2 == NULL){
                    printf("Allocation failed\n");
                    goto end;
                }
                res = fread (buffer2,sizeof(char),modulo,ptr);    //get the chunk from file pointer
                inserttolist(sPtr,res,isn,buffer2,1, res,modulo);
                break;
            }
        }
        end:
        
        fclose(ptr);
            
    }
    For the inserttolist:
    Code:
    void inserttolist(Flist *sPtr, int chunksize, int isn, char *buffer, int last, int res, int modulo){
        while(sPtr->next != NULL){        
                sPtr = sPtr->next;                    //find end of list
                    
            }
            sPtr->next = (struct flist *)malloc(sizeof(struct flist));    //allocate memory for node
            sPtr->next-> res = res;
            sPtr->next->chunksize = chunksize;                //size of the chunk pointed by sptr->chunk
            sPtr->next->isn = isn;                        //segment number of this chunk
            sPtr->next->next = NULL;
            sPtr->next->acked = 0;
            if(last == 0){
                sPtr->next->last = 0;
                sPtr->next->chunk = (char *)malloc(sizeof(char)*chunksize);        //set sptr->chunk to point to the actual chunk        
                memcpy(sPtr->next->chunk,buffer,chunksize);
            }
            else{
                sPtr->next->last = 1;
                sPtr->next->chunk = (char *)malloc(sizeof(char)*modulo);        //set sptr->chunk to point to the actual chunk
                memcpy(sPtr->next->chunk,buffer,modulo);
            }
    
    
    }
    Thank you for taking the time in reading this and I hope you can help

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    parse_file() allocates memory but never releases it. If you call the function more than once, that results in a memory leak. Eventually that will cause malloc() to fail.

    Your code attempts to perform memcpy() on the pointers returned by malloc() BEFORE checking if the pointer is NULL. The check for NULL needs to occur (to determine if malloc() failed) before calling memcpy().

    If modulo is ever not equal to chunksize, then your list never records the actual amount of memory allocated. Any code that believes that some_pointer->chunksize records the amount of memory allocated to some_pointer->chunk will potentially run past the end of such allocated memory.

    Quite frankly, your code is a mess. The above are problems I picked up on a casual look. Because your code is a mess, there is a distinct possibility of other problems I have not detected (since I have reached the limit of how closely I will look at messy code).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    goto is considered harmful here:
    Code:
    /*obtain number of chunks to be made*/
    if(filesize<chunksize){
        printf("File size is too small for chunk\n");
        quotient = 0;
        modulo = filesize;
        goto start;
    }
    quotient = filesize/chunksize;
    modulo = filesize%chunksize;
        printf("Modulo is %i\n",modulo);
    
    start:
    You should have written:
    Code:
    /*obtain number of chunks to be made*/
    if (filesize < chunksize) {
        printf("File size is too small for chunk\n");
        quotient = 0;
        modulo = filesize;
    } else {
        quotient = filesize / chunksize;
        modulo = filesize % chunksize;
        printf("Modulo is %i\n", modulo);
    }
    Instead of writing:
    Code:
    buffer1 = (char *)malloc(sizeof(char)*chunksize);
    I suggest:
    Code:
    buffer1 = malloc(sizeof(buffer1[0]) * chunksize);
    Personally, I feel that you are treating the last chunk as too much of a special case, complicating the logic. Just have one buffer of size chunksize to read into. Then, the last chunk is special in that the buffer size is smaller (i.e., instead of passing last and modulo, you just pass modulo as buffer_size, whereas in other cases you pass chunksize as buffer_size). However, you then have to worry about how the size of this buffer is going to be recorded. If it makes sense, you might want to use chunksize as buffer_size.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By raczzoli in forum C Programming
    Replies: 4
    Last Post: 07-18-2011, 06:49 PM
  2. MPI Problem gives segmentation fault
    By confused_coder in forum C Programming
    Replies: 6
    Last Post: 09-07-2009, 09:34 PM
  3. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  4. problem with segmentation fault
    By cBegginer in forum C Programming
    Replies: 13
    Last Post: 05-15-2005, 11:51 AM
  5. Segmentation fault problem
    By robsmith in forum C Programming
    Replies: 1
    Last Post: 05-08-2005, 05:33 PM