[英]how to free correctly the pointers
This is a function that i've written: 这是我编写的函数:
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;
}
into the main program i have char **files
and then the part where i get the count is count = file_list("./", &files);
进入主程序,我有char **files
,然后我得到计数的部分是count = file_list("./", &files);
What is my problem? 我怎么了
Everbody know that the dynamically allocated memory they (the pointers) might refer to , must be freed but if i free the pointers (with the for loop) then into the main program i got an unexpected behaviour during the file list (duplicate file name, no file name, etc) . 大家都知道必须释放它们(指针)可能引用的动态分配的内存 ,但是如果我释放指针(使用for循环),则进入主程序后,文件列表期间会出现意外行为 (重复的文件名,没有文件名等) 。
In fact if i don't free the pointers all work perfectly. 实际上,如果我不释放指针,那么所有指针都将完美工作。
So my question is: how to free these pointers? 所以我的问题是:如何释放这些指针?
Thanks in advance! 提前致谢!
Everbody know that the pointers must be freed but if i free the pointers (with the for loop) then into the main program i got an unexpected behaviour during the file list (duplicate file name, no file name, etc). 谁都知道必须释放指针,但是如果我释放指针(使用for循环),则进入主程序后,文件列表期间会出现意外行为(重复的文件名,无文件名等)。
Your problem is that you allocate and free in the same function, which render your function basically useless (if I understand correctly anyway). 您的问题是您在同一个函数中进行分配和释放,这使您的函数基本上无用(如果我仍然正确理解的话)。 If you free in the same function, after it returns (ie: in the "main program"), you end up accessing memory segments that have been released to the operating system, which is undefined behavior. 如果释放相同的功能,则在返回后(即:在“主程序”中),最终将访问已释放到操作系统的内存段,这是未定义的行为。
You'd need two functions, one for the allocation (the one above), and one to free it once you're done, per example: 您需要两个函数,一个用于分配(上面的一个),一个在完成后将其释放的函数,例如:
char** files;
uint32_t count = file_list("./", &files);
// do something with files here
file_list_free(&files, count);
Keep in mind that your free function will need to know the count
to prevent a buffer overrun. 请记住,您的自由函数将需要知道count
以防止缓冲区溢出。
There are other problems with your code (eg: not checking the return value of calloc
, etc.), but it would be too long to cover them all here (and don't necessarily relate to your actual question). 您的代码还有其他问题(例如:不检查calloc
的返回值等),但是将其全部覆盖在这里太长了(不一定与您的实际问题有关)。
For starters, your ls parameter is a char***
, so if that's what you were going for, you need to have an inner loop to free up all of the inner pointers ( **ls
) before freeing up each of the other ones ( *ls
). 对于初学者,您的ls参数是一个char***
,因此,如果char***
,则需要释放一个内部循环以释放所有内部指针( **ls
),然后释放其他每个内部指针。 ( *ls
)。 If you only want double indirection on ls
, then get rid of one of the *s in your parameter declaration. 如果只想在ls
上进行双重间接访问,请在参数声明中摆脱* s之一。
(BTW, you needn't use array notation in your loop to free up the pointers (or anywhere else that you access the allocated elements in ls
). free(*(ls + count));
is usually the more accepted idiom. Pointer arithmetic works regardless of what the data type is (other than void
), because the compiler takes that into account.) (顺便说一句,您不必在循环中使用数组表示法来释放指针(或在ls
访问分配的元素的其他任何地方) ls
free(*(ls + count));
通常是更被接受的习惯用法。无论数据类型是什么(除void
),算术均有效,因为编译器已将其考虑在内。)
You have to define an extra function, so the caller can free the data when it is done using it: 您必须定义一个额外的函数,以便调用者可以在使用完数据后释放数据:
void free_file_list(char ***ls, int count) {
for(int i=0; i<count; i++){
free((*ls)[i]);
}
free(*ls);
}
Your documentation then must explain that each call to file_list
must be matched with a call to free_file_list
. 然后,您的文档必须说明,每次对file_list
调用都必须与对free_file_list
的调用相匹配。
I would store count
in a struct like this, though: 我将count
存储在这样的结构中:
struct {
char ***ls;
int count;
} FILE_LIST;
Free the pointers in the main program, after you've finished using them. 使用完指针后,释放它们在主程序中的指针。
You need to free *ls
as well (again, after you've finished with it). 您还需要释放*ls
(同样,在完成后)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.