简体   繁体   English

如何正确释放指针

[英]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.

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