简体   繁体   中英

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM