【问题标题】:Freeing copies to allocated memory (by getline() function)将副本释放到分配的内存(通过 getline() 函数)
【发布时间】:2021-09-07 14:53:24
【问题描述】:

我编写了以下函数来读取文本文件的行并将它们保存到全局数组中:

/* maximum number of lines allowed in one source file */
#define MAXSRCLNS 100
char *G_source_lines[MAXSRCLNS];    /* source lines */
/* number of source lines saved into source_ */
size_t G_source_lines_count = 0;

/*
 * reads the source file 'path' and puts non-empty lines into the
 * array G_source_lines. increments the number of lines
 * G_source_lines_count for each line saved.
 */
void read_lines(char *path)
{
  FILE *stream;
  stream = fopen(path, "r");
  if (!stream) {
    fprintf(stderr, "can't open source '%s'\n", path);
    exit(EXIT_FAILURE);
  }
  char *lnptr = NULL;
  size_t n = 0;
  while ((getline(&lnptr, &n, stream) != -1)) {
    /* throw away empty lines */
    if (!isempty(lnptr)) {
      /* assert(("line count too large", G_source_lines_count < MAXSRCLNS)); */
      G_source_lines[G_source_lines_count++] = lnptr;
    } else {
      /* I don't save an empty line in the G_source_lines for later
     freeing, so free the allocation right here! */
      free(lnptr);
    }
    lnptr = NULL;
  }
  /* free the lnptr variable defined and allocated on this stack */
  /* don't forget to free it's copies in G_source_lines when done with it */
  free(lnptr);
  fclose(stream);
}

void free_source_lines(void)
{
  for (size_t ln = 0; ln < G_source_lines_count; ++ln)
    free(G_source_lines[ln]);
}


我不确定通过保存在lnptr 中的getline 将指向分配内存的指针复制到G_source_lines 中是否有必要释放这些副本,因为free_source_lines 函数在完成G_souce_lines 后应该这样做,或者最后在 read_line 中释放lnptr 一次就足够了吗?

【问题讨论】:

  • 是的,你需要在free_source_lines()释放所有东西。
  • 但是free(lnptr) 并没有什么坏处,因为free(NULL) 什么也没做。
  • @Barmar 来自 getline 的手册页:If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed.
  • 因此,您可以将lnptr = NULL; 移动到if 部分,并完全删除else 部分(保留分配的缓冲区)。函数末尾的最终free(lnptr); 将释放任何未使用的缓冲区。
  • 下一次调用getline() 时,不需要的“空”缓冲区将被重用或重新分配,因此在读取所有行之前无需释放。不过,释放它并没有什么坏处,只要您从不将“已保存”或“已释放”指针值传回 getline

标签: c getline


【解决方案1】:

是的,必须在free_source_lines() 中释放它们。

由于您在每次调用 getline() 之前将 lnptr 设置为 NULL,因此每次都将其设置为指向不同缓冲区的指针。最后对free(lnptr) 的调用仅释放在最终失败调用期间分配的缓冲区,而不是保存在G_source_lines 中的任何缓冲区。

【讨论】:

  • 最后的free(lnptr)是针对getline返回-1的情况,从而跳出while循环
猜你喜欢
  • 1970-01-01
  • 2012-01-31
  • 2012-11-06
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
相关资源
最近更新 更多