Program crashes even though free is executed

Given this code , which is a part of a bigger code , but it's the blame .

In int main() I do this :

int main(int argc, char* argv[]) {

// code 

// code 

path2 = (char*)malloc(strlen(currentDir)*sizeof(char));

traverseDirectories(path2 , filename);

free(path2);
}

The error :

a@ubuntu:~/Desktop$ ./exer4 fsdfsdfdafsd/ exer4
Could not open: No such file or directory
*** glibc detected *** ./exer4: free(): invalid next size (normal): 0x08b54038 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6ebc2)[0x93ebc2]
/lib/i386-linux-gnu/libc.so.6(+0x6f862)[0x93f862]
/lib/i386-linux-gnu/libc.so.6(cfree+0x6d)[0x94294d]
/lib/i386-linux-gnu/libc.so.6(fclose+0x154)[0x92e0b4]
/lib/i386-linux-gnu/libc.so.6(perror+0xc5)[0x920a45]
./exer4[0x8048f52]
./exer4[0x8048b34]
./exer4[0x8048a99]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x8e9113]
./exer4[0x80487c1]
======= Memory map: ========
00398000-003b4000 r-xp 00000000 08:01 394171     /lib/i386-linux-gnu/libgcc_s.so.1
003b4000-003b5000 r--p 0001b000 08:01 394171     /lib/i386-linux-gnu/libgcc_s.so.1
003b5000-003b6000 rw-p 0001c000 08:01 394171     /lib/i386-linux-gnu/libgcc_s.so.1
008d0000-00a46000 r-xp 00000000 08:01 394150     /lib/i386-linux-gnu/libc-2.13.so
00a46000-00a48000 r--p 00176000 08:01 394150     /lib/i386-linux-gnu/libc-2.13.so
00a48000-00a49000 rw-p 00178000 08:01 394150     /lib/i386-linux-gnu/libc-2.13.so
00a49000-00a4c000 rw-p 00000000 00:00 0 
00b5a000-00b5b000 r-xp 00000000 00:00 0          [vdso]
00c4b000-00c69000 r-xp 00000000 08:01 394137     /lib/i386-linux-gnu/ld-2.13.so
00c69000-00c6a000 r--p 0001d000 08:01 394137     /lib/i386-linux-gnu/ld-2.13.so
00c6a000-00c6b000 rw-p 0001e000 08:01 394137     /lib/i386-linux-gnu/ld-2.13.so
08048000-0804a000 r-xp 00000000 08:01 947365     /home/a/Desktop/exer4
0804a000-0804b000 r--p 00001000 08:01 947365     /home/a/Desktop/exer4
0804b000-0804c000 rw-p 00002000 08:01 947365     /home/a/Desktop/exer4
08b54000-08b75000 rw-p 00000000 00:00 0          [heap]
b7600000-b7621000 rw-p 00000000 00:00 0 
b7621000-b7700000 ---p 00000000 00:00 0 
b775f000-b7760000 rw-p 00000000 00:00 0 
b776f000-b7771000 rw-p 00000000 00:00 0 
bf87d000-bf89e000 rw-p 00000000 00:00 0          [stack]
Aborted

And here are the methods :

int traverseDirectories(char * path , const char * filename)
{

    // printf("\nCurrent path is :%s\n " , path);
    struct dirent *direntp = NULL;
    DIR *dirp = NULL;
    size_t path_len;
    char full_name[BUFFER];
    strcpy(full_name, path);

    displayAllFiles(full_name , filename);  // display the file details to STDOUT

// code 
// code 

}


void displayAllFiles(char * directory , char * filename)
{
    struct stat st;
    DIR *dir;
    struct dirent *ent;

    char fullPathDirectory[BUFFER];
    char fileDetails[BUFFER];

    memset(fullPathDirectory, '\0', BUFFER);   // reset the array of the input
    memset(fileDetails, '\0', BUFFER);   // reset the array of the input

    dir = opendir (directory);

    if (dir != NULL)
    {

         // print all the files and directories within directory
         while ((ent = readdir (dir)) != NULL)
         {
             if (strcmp(ent->d_name , filename) == 0)
             {
                  // printf("\nFile found!\n");

                  strcpy(fullPathDirectory , directory);
                  strcat(fullPathDirectory , "/");
                  strcat(fullPathDirectory , filename);

                  if (lstat(fullPathDirectory, &st) < 0)
                  {
                      perror(ent->d_name);
                      putchar('\n');
                      continue;
                  }

                  displayProperties(&st , fileDetails);

                  printf("\n%s" , fileDetails); // print file details
                  printf("%s\n" , fullPathDirectory); // print file path
             }

         }
         closedir (dir);
    }

    else
    {
     // could not open directory
     perror ("Could not open");
     free(directory);
     exit(EXIT_FAILURE);
    }

}

I free the directory in method displayAllFiles , but even though I get this message when executing :

./exer4 fsdfsdfdafsd/ exer4

The program doesn't find the folder fsdfsdfdafsd , and this is OK , but why does it print all the backtrace ? all I wanted it to do is to print that no such file or directory .

Any ideas ?

Thanks

Answers


I write a test code to simulate your problem.

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 void problem(char * addr)
  5 {
  6     free(addr);
  7 }
  8 
  9 int func(char * buf)
 10 {
 11     char name[10];
 12 
 13 
 14 
 15     problem(name);
 16 
 17     return 0;
 18 }
 19 
 20 int main(void)
 21 {
 22     char *string;
 23 
 24     string = NULL;
 25     string = malloc(10);
 26     if(string == NULL)
 27         return -1;
 28 
 29     func(string);
 30     free(string);
 31     return 0;
 32 }
 33 

run valgrind give the message.

==17451== Invalid free() / delete / delete[] / realloc()
==17451==    at 0x59CFC: free (in /usr/local/lib/valgrind/vgpreload_memcheck-x86-freebsd.so)
==17451==    by 0x8048490: problem (main.c:6)
==17451==    by 0x80484B0: func (main.c:15)
==17451==    by 0x8048500: main (main.c:29)
==17451==  Address 0xbebfec2e is on thread 1's stack

You can not free a address that is not allocate by malloc, it will cause a problem.


A few quick observations:

  1. Don't cast the return of malloc().
  2. sizeof (char) is 1.
  3. Strings need room for the '\0' termination character.

You call free(directory) in displayAllFiles() when directory comes from a local variable in traverseDirectories().

Generally, you shouldn't call exit() there, but just return a indicator for an error, which the caller can (and should) handle.


This is some piece of your code.

char full_name[BUFFER];    
displayAllFiles(full_name , filename); 
.....
void displayAllFiles(char * directory , char * filename)
....
free(directory);

argument directory is not allocated by malloc, free a address that is not allocated by malloc will cause undefined behavior.


The problem is here :

a@ubuntu:~/Desktop$ ./exer4 fsdfsdfdafsd/ exer4
Could not open: No such file or directory
*** glibc detected *** ./exer4: free(): invalid next size (normal): 0x08b54038 ***

The thing is , when I allocate this :

path2 = (char*)malloc(strlen(currentDir)*sizeof(char));

and later on change the size of the string that path2 points to , and I try to free back in main a string with a length of strlen(currentDir) , then I get this :

 invalid next size (normal): 0x08b54038 ***

This means that I try to free a memory with some other size , and this is incorrect of course . That's why I did this : path2 = malloc(BUFFER*sizeof(char)); , and everything worked out OK .

Thanks everybody !


Need Your Help

Is it possible to make it in flash that objects move only on whole pixel width and heigth?

flash pixels

My objects sometimes have possition 20.31 for example on x axis, is it possible to make it so they move in a grid maybe, 1px wide grid so there are no decimals in position?