【问题标题】:Prevent leak after Ctrl+C when using read and malloc in a loop在循环中使用 read 和 malloc 时防止 Ctrl+C 后泄漏
【发布时间】:2013-11-23 22:18:25
【问题描述】:

我必须做一个项目,用 C 创建一个 shell。 将有一个 while 循环等待字符读入输入。

我认为将我们读取的字符存储在使用malloc 的指针中比存储在具有固定大小的缓冲区(字符数组)中更好,因为我们不知道将发送多少个字符。这样,如果需要,我可以在指针上使用realloc 以获得更大的大小。

我在 valgrind 中注意到,当程序完成读取字符并等待新字符时;如果我按 Ctrl+C,就会出现内存泄漏。 我发现防止这种情况的唯一解决方案是在发送每个命令后释放指针。

这是个好主意还是有更好的方法来做到这一点?有关信息,我正在读取缓冲区 buf 中的字符,然后将字符串连接到指针 str。代码如下:

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define READ_SIZE 1024

int main()
{
  char  buf[READ_SIZE];
  char  *str;
  int   ret;
  int   size;
  int   max;

  str = NULL;
  size = 0;
  max = READ_SIZE;
  write(1, "$> ", 3);
  while((ret = read(0, buf, READ_SIZE)))
    {
      if (str == NULL)
      {
        if ((str = malloc(READ_SIZE + 1)) == NULL)
          return EXIT_FAILURE;
        strncpy(str, buf, ret);
        str[ret] = '\0';
      }
      else
        str = strncat(str, buf, ret);
      if (strncmp(&buf[ret - 1], "\n", 1) == 0)
      {
        str[size + ret - 1] = '\0';
        printf("%s\n", str);
        size = 0;
        max = READ_SIZE;
        free(str);
        str = NULL;
        write(1, "$> ", 3);
      }
      else if (size + ret == max)
      {
        max *= 2;
        size += READ_SIZE;
        if ((str = realloc(str, max + 1)) == NULL)
          return EXIT_FAILURE;
      }
      else
        size += READ_SIZE;
    }
  free(str);
  return EXIT_SUCCESS;
}

【问题讨论】:

    标签: c


    【解决方案1】:

    这里有几件事要说 -

    1. 如果您的程序在 ctrl+C 上干净地退出对您很重要,那么您必须添加一个 signal handler 来进行清理,而不是在 ctrl+C 上立即退出。请注意,您的解决方案并不完美:如果您在 alloc 和 dealloc 之间的瞬间按 ctrl+c,您仍然会显示泄漏。
    2. 在程序退出时清理泄漏可以说是不重要的,因为在这种情况下操作系统会清理所有剩余的内存。反对这一点的论点是,在软件工程中,您的程序现在可能成为将来另一个程序的库,并且它的泄漏将变得危险。现在你的程序在任何 SIGINT 上泄漏;即使进程继续运行,您的程序接口的一部分是否要保证在 SIGINT 上清理内存,这取决于您。我个人无法想象这很重要。
    3. 您绝对无法防止 ctrl+Z 泄漏,所以不要过分强调完美。

    换句话说 - 我不认为这很重要,但我已尽力解释为什么会这样,如果你坚持,你可以用 ctrl+C 解决它。

    【讨论】:

      猜你喜欢
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多