这是我写的一个函数:
uint32_t file_list(char *path, char ***ls){
DIR *dp;
//uint32_t i;
struct stat fileStat;
struct dirent *ep = NULL;
uint32_t len, count = 0;
int file = 0;
*ls = NULL;
dp = opendir (path);
if(dp == NULL){
fprintf(stderr, "no dir: %s\n", path);
exit(1);
}
ep = readdir(dp);
while(NULL != ep){
count++;
ep = readdir(dp);
}
rewinddir(dp);
*ls = calloc(count, sizeof(char *));
count = 0;
ep = readdir(dp);
while(ep != NULL){
if((file = open(ep->d_name, O_RDONLY)) < 0){
perror("apertura file");
exit(1);
}
if(fstat(file, &fileStat) != 0){
perror("filestat");
free(*ls);
close(file);
exit(EXIT_FAILURE);
}
close(file);
if(S_ISDIR(fileStat.st_mode)){
len = strlen(ep->d_name);
(*ls)[count] = malloc(len+5); /* lunghezza stringa + "DIR \n" */
strcpy((*ls)[count], "DIR "); /* copio DIR */
strcat((*ls)[count++], ep->d_name); /* concateno la stringa DIR con il nome della dir */
ep = readdir(dp);
}
else{
(*ls)[count++] = strdup(ep->d_name);
ep = readdir(dp);
}
}
/*for(i=0; i<count; i++){
free((*ls)[count]);
}*/
(void)closedir(dp);
return count;
}
进入主程序我有char **files
然后我得到计数的部分是count = file_list("./", &files);
我的问题是什么?
有人知道他们(指针)可能引用的动态分配的内存,必须被释放但是如果我释放指针(带有for循环)然后进入主程序我在文件列表中找到了意外行为 (重复文件名,没有文件名等)。
实际上如果我不释放所有指针完美地工作。
所以我的问题是:如何释放这些指针?
提前谢谢!
答案 0 :(得分:2)
永远知道指针必须被释放但是如果我释放指针(使用for循环)然后进入主程序我在文件列表中遇到了意外的行为(重复文件名,没有文件名等)。 / p>
你的问题是你在相同的功能中分配和释放,这使你的功能基本无用(如果我理解正确的话)。如果你使用相同的函数,在它返回后(即:在“主程序”中),你最终会访问已经释放到操作系统的内存段,这是未定义的行为。
你需要两个函数,一个用于分配(上面的一个),一个用于在完成后释放它,例如:
char** files;
uint32_t count = file_list("./", &files);
// do something with files here
file_list_free(&files, count);
请注意,您的免费功能需要知道count
以防止缓冲区溢出。
您的代码还存在其他问题(例如:不检查calloc
的返回值等),但是在这里覆盖它们太长了(并不一定与您的实际相关)问题)。
答案 1 :(得分:1)
对于初学者来说,你的ls参数是char***
,所以如果这就是你想要的,你需要有一个内循环来释放所有内部指针(**ls
),然后释放其他每一个(*ls
)。如果您只想在ls
上进行双重间接,那么请在参数声明中删除其中一个*。
(顺便说一下,你不需要在你的循环中使用数组表示法来释放指针(或者你在ls
中访问分配元素的任何其他地方)。free(*(ls + count));
通常是更被接受的成语无论数据类型是什么(void
除外),指针算法都可以工作,因为编译器会考虑到这一点。)
答案 2 :(得分:1)
您必须定义一个额外的函数,因此调用者可以在使用它时释放数据:
void free_file_list(char ***ls, int count) {
for(int i=0; i<count; i++){
free((*ls)[i]);
}
free(*ls);
}
然后,您的文档必须说明,对file_list
的每次通话都必须与对free_file_list
的通话相匹配。
我会将count
存储在这样的结构中,但是:
struct {
char ***ls;
int count;
} FILE_LIST;
答案 3 :(得分:0)
完成使用后,释放主程序中的指针。
你也需要释放*ls
(再次,在你完成之后)。