4 Replies - 1103 Views - Last Post: 01 June 2010 - 06:00 PM Rate Topic: -----

#1 Korupt  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 21
  • View blog
  • Posts: 185
  • Joined: 22-June 08

Fclose and Free Segmentation Faults

Posted 01 June 2010 - 04:12 PM

I'm doing the exercises from the K&R book and I've ran into a problem. The point of the problem is to go through a file and replace all the tabs with 4 spaces. The program works fine and the new file has all it's tabs removed but at the end when I try to free the memory of the buffered file and close the stream I get a segmentation fault. The program works in the following order: 1) Open the file; 2) Count the tabs; 3)Allocate memory for the new file in a buffer; 4) Copy the file in memory while removing the tabs; 5) Reopen the file with writing permissions and write what you copied from memory in it; 6) Close file and free the memory. Step 6 is where my program is giving a segmentation fault. Here's the code:

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

int main(int argc, char **argv)
{
    if (argc < 2)
    {
        printf("Please provide a file to detab\n");
        return -1;
    }

    FILE *file = fopen(argv[1], "r");
    char *buffer = NULL;

    if (file == NULL)
    {
        printf("Unable to open \'%s\'.\n", argv[1]);
        return -1;
    }

    int c;
    int tabs = 0;

    /* Count the number of tabs */
    while((c = getc(file)) != EOF)
    {
        if (c == '\t')
            ++tabs;
    }

    if (tabs <= 0)
    {
        printf("No tabs found in \'%s\'.\n", argv[1]);
        fclose(file);
        return -1;
    }

    rewind(file);
    buffer = malloc((sizeof(char) * fseek(file, 0, SEEK_END)) + (sizeof(char) * 3 * tabs) + sizeof(char));

    if (buffer == NULL)
    {
        printf("Unable to allocate enough memory for \'%s\'.\n", argv[1]);
        fclose(file);
        return -1;
    }

    rewind(file);

    /* Load file in memory and detab */
    int i;
    for (i = 0;(c = getc(file)) != EOF;i++)
    {
        if (c == '\t')
        {
            buffer[i] = ' ';
            buffer[++i] = ' ';
            buffer[++i] = ' ';
            buffer[++i] = ' ';
        }
        else
            buffer[i] = (char)c;
    }

    buffer[i] = '\0';

    if (freopen(argv[1], "w", file) == NULL)
    {
        printf("Unable to reopen \'%s\' for writing.\n", argv[1]);
        fclose(file);
        free(buffer);
        return -1;
    }

    if (fputs(buffer, file) == EOF)
    {
        printf("An error occured while writting to \'%s\'.\n", argv[1]);
        fclose(file);
        free(buffer);
        return -1;
    }

    printf("\'%s\' was detabed successfully.\n", argv[1]);
    fclose(file);
    free(buffer);
    return 0;
}


Sample run:

$ ./KR ~/Desktop/test.txt 
'/home/niki/Desktop/test.txt' was detabed successfully.
Segmentation fault



With file:

fads     dfaskf            sdgl;sd



Another run with a different file:

$ ./KR ~/Desktop/test.txt 
'/home/niki/Desktop/test.txt' was detabed successfully.
*** glibc detected *** ./KR: free(): invalid next size (fast): 0x0918d170 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0xb7661591]
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0xb7662de8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb7665ecd]
./KR[0x8048918]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb760cbd6]
./KR[0x80485c1]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:04 9961596    /home/niki/workspace/KR/bin/Debug/KR
08049000-0804a000 r--p 00000000 08:04 9961596    /home/niki/workspace/KR/bin/Debug/KR
0804a000-0804b000 rw-p 00001000 08:04 9961596    /home/niki/workspace/KR/bin/Debug/KR
0918d000-091ae000 rw-p 00000000 00:00 0          [heap]
b7400000-b7421000 rw-p 00000000 00:00 0 
b7421000-b7500000 ---p 00000000 00:00 0 
b75f5000-b75f6000 rw-p 00000000 00:00 0 
b75f6000-b7749000 r-xp 00000000 08:04 8126517    /lib/tls/i686/cmov/libc-2.11.1.so
b7749000-b774a000 ---p 00153000 08:04 8126517    /lib/tls/i686/cmov/libc-2.11.1.so
b774a000-b774c000 r--p 00153000 08:04 8126517    /lib/tls/i686/cmov/libc-2.11.1.so
b774c000-b774d000 rw-p 00155000 08:04 8126517    /lib/tls/i686/cmov/libc-2.11.1.so
b774d000-b7750000 rw-p 00000000 00:00 0 
b7750000-b776d000 r-xp 00000000 08:04 8126548    /lib/libgcc_s.so.1
b776d000-b776e000 r--p 0001c000 08:04 8126548    /lib/libgcc_s.so.1
b776e000-b776f000 rw-p 0001d000 08:04 8126548    /lib/libgcc_s.so.1
b776f000-b7770000 rw-p 00000000 00:00 0 
b7770000-b7794000 r-xp 00000000 08:04 8126566    /lib/tls/i686/cmov/libm-2.11.1.so
b7794000-b7795000 r--p 00023000 08:04 8126566    /lib/tls/i686/cmov/libm-2.11.1.so
b7795000-b7796000 rw-p 00024000 08:04 8126566    /lib/tls/i686/cmov/libm-2.11.1.so
b7796000-b787f000 r-xp 00000000 08:04 16781300   /usr/lib/libstdc++.so.6.0.13
b787f000-b7880000 ---p 000e9000 08:04 16781300   /usr/lib/libstdc++.so.6.0.13
b7880000-b7884000 r--p 000e9000 08:04 16781300   /usr/lib/libstdc++.so.6.0.13
b7884000-b7885000 rw-p 000ed000 08:04 16781300   /usr/lib/libstdc++.so.6.0.13
b7885000-b788c000 rw-p 00000000 00:00 0 
b789b000-b789c000 rw-p 00000000 00:00 0 
b789d000-b789f000 rw-p 00000000 00:00 0 
b789f000-b78a0000 r-xp 00000000 00:00 0          [vdso]
b78a0000-b78bb000 r-xp 00000000 08:04 8126854    /lib/ld-2.11.1.so
b78bb000-b78bc000 r--p 0001a000 08:04 8126854    /lib/ld-2.11.1.so
b78bc000-b78bd000 rw-p 0001b000 08:04 8126854    /lib/ld-2.11.1.so
bf7f4000-bf809000 rw-p 00000000 00:00 0          [stack]
Aborted



File:

asfasdf            lj    l;j    ll;dkls
dfsdfl    l;kfl;ekfsdf
    f    eks;ldgks;dgs
gs
dg
sdg    k    skdgksd;glk



When I comment out fclose(file); and free(buffer); None of that is shown only a success message. Any help is appreciated. Thanks.

Is This A Good Question/Topic? 0
  • +

Replies To: Fclose and Free Segmentation Faults

#2 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1072
  • View blog
  • Posts: 4,532
  • Joined: 09-June 09

Re: Fclose and Free Segmentation Faults

Posted 01 June 2010 - 04:39 PM

My Knowlege is in C++ not C, but this allocatation looks wierd to me
buffer = malloc((sizeof(char) * fseek(file, 0, SEEK_END)) + (sizeof(char) * 3 * tabs) + sizeof(char)); 




The buffers allocated memory should be as big as how many bytes are in the text file.
You loop through each char in the file before the allocation, so why not create a counter for that loop and get the number of chars in the file. Then do something like

buffer = (char*)malloc(numberOfChars * sizeof(char));

The segmentation fault is probably because you are trying to read/write to unallocated memory and then you are trying to free it. But that was at a glance, maybe there is a reason for that allocation

This post has been edited by ImaSexy: 01 June 2010 - 04:40 PM

Was This Post Helpful? 1
  • +
  • -

#3 Korupt  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 21
  • View blog
  • Posts: 185
  • Joined: 22-June 08

Re: Fclose and Free Segmentation Faults

Posted 01 June 2010 - 04:47 PM

Wow that actually fixed it. Yeah, you were right that there is no need to fseek since I can just count the character in my first loop, but the + (sizeof(char) * 3 * tabs) + sizeof(char) part is still needed because in the original file a tab only took up 1 byte while in the new one it takes 4 spaces which are 4 bytes and the + 1 is for the \0 at the end of the string. I still don't understand why that fixed the problem though. Even if fseek is more inefficient why doesn't it work?

This post has been edited by Korupt: 01 June 2010 - 04:48 PM

Was This Post Helpful? 0
  • +
  • -

#4 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1072
  • View blog
  • Posts: 4,532
  • Joined: 09-June 09

Re: Fclose and Free Segmentation Faults

Posted 01 June 2010 - 04:53 PM

I dont think your understanding what the return value of fseek is.

Click me

when fseek is succesfull it returns zero

so if fseek is succesfull how many bytes are you allocating here

malloc((sizeof(char) * fseek(file, 0, SEEK_END)) + (sizeof(char) * 3 * tabs) + sizeof(char)); 



you only allocating sizeof(char) * 3 * tabs) + sizeof(char)); that many bytes which is obviously not right

This post has been edited by ImaSexy: 01 June 2010 - 04:58 PM

Was This Post Helpful? 2
  • +
  • -

#5 Korupt  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 21
  • View blog
  • Posts: 185
  • Joined: 22-June 08

Re: Fclose and Free Segmentation Faults

Posted 01 June 2010 - 06:00 PM

Ohh I see, I though fseek return the number of characters it has moved through, thanks.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1