Lucky
Lucky

Reputation: 713

Call to free causes memory corruption

This code employs malloc/free but the free doesn't work.

#include <stdio.h>
#include <errno.h>
#include <glob.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>

int main() {

        glob_t results;
        int i, rv = 0;
        time_t latestd = 0;
        time_t time = 0;
        char * latest;
        struct stat statbuf;

        latest = (char*) malloc(256);

        rv = glob("mydirectorypattern*", 0, 0, &results);

        if (rv != 0) {
                fprintf(stderr, "Something failed with glob.\n");
                exit(1);
        }

        for (i = 0; i < results.gl_pathc; i++) {
                printf("%s\n", results.gl_pathv[i]);

                if (stat(results.gl_pathv[i], &statbuf) == -1) {
                        perror("stat");
                        return errno;
                }

                if (S_ISDIR(statbuf.st_mode)) {
                        time = statbuf.st_mtime;
                        if (time > latestd) {
                                latestd = time;
                                latest = results.gl_pathv[i];
                        }
                }
        }

        printf("latest is %s\n",latest);
        //free(latest); // NOPE
        //free(&latest); // NOPE
        globfree(&results);
        return 0;
}

The error says something about corrupted memory. I thought it could be because the glob_t variable gets freed in regfree but I still get the error if I call free on latest first. How can I fix this?

*** Error in `./globstat': corrupted double-linked list: 0x0000000001d974f0 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x791eb)[0x7f305796d1eb]
/lib64/libc.so.6(+0x81173)[0x7f3057975173]
/lib64/libc.so.6(+0x82af0)[0x7f3057976af0]
/lib64/libc.so.6(cfree+0x4c)[0x7f305797a28c]
/lib64/libc.so.6(globfree64+0x43)[0x7f30579c3853]
./globstat[0x400987]
/lib64/libc.so.6(__libc_start_main+0xf1)[0x7f3057914431]
./globstat[0x40074a]
======= Memory map: ========
00400000-00401000 r-xp 00000000 fd:03 288407                             /home/jujee/cs344/344-hw2/globstat
00600000-00601000 r--p 00000000 fd:03 288407                             /home/jujee/cs344/344-hw2/globstat
00601000-00602000 rw-p 00001000 fd:03 288407                             /home/jujee/cs344/344-hw2/globstat
01d8f000-01db0000 rw-p 00000000 00:00 0                                  [heap]
7f3050000000-7f3050021000 rw-p 00000000 00:00 0 
7f3050021000-7f3054000000 ---p 00000000 00:00 0 
7f30576dd000-7f30576f3000 r-xp 00000000 fd:01 1972953                    /usr/lib64/libgcc_s-6.4.1-20170727.so.1
7f30576f3000-7f30578f2000 ---p 00016000 fd:01 1972953                    /usr/lib64/libgcc_s-6.4.1-20170727.so.1
7f30578f2000-7f30578f3000 r--p 00015000 fd:01 1972953                    /usr/lib64/libgcc_s-6.4.1-20170727.so.1
7f30578f3000-7f30578f4000 rw-p 00016000 fd:01 1972953                    /usr/lib64/libgcc_s-6.4.1-20170727.so.1
7f30578f4000-7f3057ab1000 r-xp 00000000 fd:01 1971429                    /usr/lib64/libc-2.24.so
7f3057ab1000-7f3057cb0000 ---p 001bd000 fd:01 1971429                    /usr/lib64/libc-2.24.so
7f3057cb0000-7f3057cb4000 r--p 001bc000 fd:01 1971429                    /usr/lib64/libc-2.24.so
7f3057cb4000-7f3057cb6000 rw-p 001c0000 fd:01 1971429                    /usr/lib64/libc-2.24.so
7f3057cb6000-7f3057cba000 rw-p 00000000 00:00 0 
7f3057cba000-7f3057ce0000 r-xp 00000000 fd:01 1969331                    /usr/lib64/ld-2.24.so
7f3057eba000-7f3057ebc000 rw-p 00000000 00:00 0 
7f3057edc000-7f3057edf000 rw-p 00000000 00:00 0 
7f3057edf000-7f3057ee0000 r--p 00025000 fd:01 1969331                    /usr/lib64/ld-2.24.so
7f3057ee0000-7f3057ee1000 rw-p 00026000 fd:01 1969331                    /usr/lib64/ld-2.24.so
7f3057ee1000-7f3057ee2000 rw-p 00000000 00:00 0 
7ffc3908a000-7ffc390ab000 rw-p 00000000 00:00 0                          [stack]
7ffc391d0000-7ffc391d3000 r--p 00000000 00:00 0                          [vvar]
7ffc391d3000-7ffc391d5000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)

Upvotes: 0

Views: 124

Answers (1)

bruno
bruno

Reputation: 32586

I still get the error if I call free on latest first. How can I fix this?

you can only free dynamic allocated memory, and each block must be freed only one time

Doing

latest = results.gl_pathv[i];

you set latest to the address a resource set by glob, and you lost the result of malloc creating a memory leak.

You do not know how glob manages the memory, you cannot suppose results.gl_pathv[i] values the address of a dynamically allocated block, and even this is the case doing both

 free(latest);
 globfree(&results);

that resource is freed two times

So if you want to save the resource do a deep copy rather than saving the pointer, replace

  latest = results.gl_pathv[i];

by

    strcpy(latest, results.gl_pathv[i]);

Then at the end use

free(latest);

and not the invalid

 free(&latest);

because &latest point into the stack

You suppose the max path is 256, better to #include <limit.h> and use MAX_PATH

In case you do not found your directory the allocated block is never initialized, so when you print it you have an undefined behavior, better to do result[0] = 0; just after the allocation

If you want to use the last path long time you can save memory using realloc

Upvotes: 1

Related Questions