Reputation: 713
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
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