0

I have a strange problem when running a C program in Linux. It compiles without any errors, but when I run it I get this error message:

*** Error in `./catter': munmap_chunk(): invalid pointer: 0x00007fffc7953310 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3ee787bc17]
./catter[0x4007d3]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x3ee7821b75]
./catter[0x400589]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:09 12200149                           /home/sasha/catter
00600000-00601000 r--p 00000000 08:09 12200149                           /home/sasha/catter
00601000-00602000 rw-p 00001000 08:09 12200149                           /home/sasha/catter
01301000-01322000 rw-p 00000000 00:00 0                                  [heap]
30a8200000-30a8215000 r-xp 00000000 08:08 795604                         /usr/lib64/libgcc_s-4.8.1-20130603.so.1
30a8215000-30a8414000 ---p 00015000 08:08 795604                         /usr/lib64/libgcc_s-4.8.1-20130603.so.1
30a8414000-30a8415000 r--p 00014000 08:08 795604                         /usr/lib64/libgcc_s-4.8.1-20130603.so.1
30a8415000-30a8416000 rw-p 00015000 08:08 795604                         /usr/lib64/libgcc_s-4.8.1-20130603.so.1
3ee7400000-3ee7421000 r-xp 00000000 08:08 786482                         /usr/lib64/ld-2.17.so
3ee7620000-3ee7621000 r--p 00020000 08:08 786482                         /usr/lib64/ld-2.17.so
3ee7621000-3ee7622000 rw-p 00021000 08:08 786482                         /usr/lib64/ld-2.17.so
3ee7622000-3ee7623000 rw-p 00000000 00:00 0 
3ee7800000-3ee79b6000 r-xp 00000000 08:08 786735                         /usr/lib64/libc-2.17.so
3ee79b6000-3ee7bb6000 ---p 001b6000 08:08 786735                         /usr/lib64/libc-2.17.so
3ee7bb6000-3ee7bba000 r--p 001b6000 08:08 786735                         /usr/lib64/libc-2.17.so
3ee7bba000-3ee7bbc000 rw-p 001ba000 08:08 786735                         /usr/lib64/libc-2.17.so
3ee7bbc000-3ee7bc1000 rw-p 00000000 00:00 0 
7f997a36e000-7f997a371000 rw-p 00000000 00:00 0 
7f997a392000-7f997a395000 rw-p 00000000 00:00 0 
7fffc7935000-7fffc7956000 rw-p 00000000 00:00 0                          [stack]
7fffc795c000-7fffc795e000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

Here is the code:

#include<stdio.h>
#include<stdlib.h>
int FILEERROR_ = 0;
char *ReadFile(char *filename, char *permissions)
{
    char output[FileSize(filename) + 1];//1 for a start
    char c;
    FILE *fp;
    int i = 0;
    fp = fopen(filename, permissions);
    while((c = fgetc(fp)) != EOF)
    {
        output[i] = c;
        i++;
    }
    fclose(fp);
    char *allo = &output[0];
    return allo;
}
int FileSize(char *filename)
{
    int i = 0;
    FILE *fp;
    fp = fopen(filename, "r");
    while(fgetc(fp) != EOF)
    {       
        i++;
    }
    fclose(fp);
    return i;
}
int main()
{
    char *read = ReadFile("a.out", "r");
    printf("%s", read);
    free(read);
    return 0;
}

If this is relevant, I am using Fedora Linux, 64-bit with a GCC C Compiler.

3
  • Start with building with debug information (add the -g flag to gcc). Then Valgrind will be able to use that information to print source files and line numbers. Commented Dec 10, 2013 at 7:31
  • Program received signal SIGABRT, Aborted. 0x0000003ee7835a19 in raise () from /lib64/libc.so.6 Commented Dec 10, 2013 at 7:34
  • You don't have a malloc, calloc or realloc. What are you trying to free? Commented Dec 10, 2013 at 7:35

4 Answers 4

2

You're returning stack-variables in ReadFile()

char output[FileSize(filename) + 1];//1 for a start
...
char *allo = &output[0];
return allo;

So the returning pointer is pointing to an invalid memory, you should not free it. Instead, if you really want this, you should allocate memory in it:

char* output = (char*)malloc([FileSize(filename) + 1);//1 for a start
...
char *allo = &output[0];
return allo;

Then you can free the pointer. But this is not a suggested way.

A better way is to allocate the memory out of ReadFile, and pass the pointer into it. ReadFile is only responsible to read and save the content into the pointer. Your main() is responsible to allocate and free the memory.

Sign up to request clarification or add additional context in comments.

4 Comments

@KarolyHorvath - Controversial practice :-)
@Abhineet It is only fatal practice in C90. C99 removed "implicit int" for functions without a prototype. However, casting the result of malloc suggests that you don't quite know what you are doing or how the C language works, so I would call it bad practice.
@KarolyHorvath Writing return (allo); is also harmless practice. Does that mean that it is good practice? No, just like casting the result of malloc, it is superfluous clutter, which originates from insecurity about how the C language actually works.
I didn't say it is good. But saying it's fatal is a lie. /off
1

The error is with char output[FileSize(filename) + 1]; line as you are defining output in a function and after the function returns that memory space for output is also freed. So your pointer allo points to NULL.

Thus you return NULL and read pointer is NULL.

You can try below code.

#include<stdio.h>
#include<stdlib.h>
int FILEERROR_ = 0;
void ReadFile(char *filename, char *permissions,char* output)
{
//char output[FileSize(filename) + 1];//1 for a start
//char *output = (char*)malloc(FileSize(filename)+1);
char c;
FILE *fp;
int i = 0;
fp = fopen(filename, permissions);
while((c = fgetc(fp)) != EOF)
{
    output[i] = c;
    i++;
}
fclose(fp);
//char *allo = &output[0];
//return allo;
}
int FileSize(char *filename)
{
int i = 0;
FILE *fp;
fp = fopen(filename, "r");
while(fgetc(fp) != EOF)
{
    i++;
}
fclose(fp);
return i;
}
int main()
{
char *read = (char*)malloc(FileSize("a.out")+1);
ReadFile("a.out", "r",read); // passing argument "read" as a pointer
printf("%s", read);
free(read);
return 0;
}

Comments

1

From the documentation,

void free (void* ptr); 

ptr::

Pointer to a memory block previously allocated with malloc, calloc or realloc.

So, you should first malloc some memory and then call free. Also, output is local to ReadFile(), so, it will die as soon you will exit ReadFile(). You should be doing something like this::

char* output = malloc(FileSize(filename) + 1);//1 for a start
/* do stuff */
char *allo = &output[0];
return allo;

4 Comments

@user2332868:: I know but make sure that you never use "typecasting" on malloc in C. It introduces a bug. And it can be fatal at times. Always include <stdlib.h> when using malloc.
And, ofcourse, you can accept the solution if it worked correctly for you ;-)
I forgot the only thing I had to change is that you accidentally added a '[' character :).
@user2332868 - Corrected :-D
0
char *ReadFile(char *filename, char *permissions)
{
    char output[FileSize(filename) + 1];//1 for a start
    char c;
    FILE *fp;
    int i = 0;
    fp = fopen(filename, permissions);
    while((c = fgetc(fp)) != EOF)
    {
        output[i] = c;
        i++;
    }
    fclose(fp);
    char *allo = &output[0];
    return allo;
}

char output[FileSize(filename) + 1] is stored in static memory so after the function finish execute its instructions, all local variable in static memory will be released , so you do not need to release it. it's better to allocate memory using malloc et then after finish using variable FREE it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.