用户在linux下按ctrl + c时如何避免内存泄漏?

在我用C和C ++编写的程序中,我将新建一个对象来完成任务,然后删除该对象。

在新对象之后但在删除对象之前的那一刻,如果用户按下ctrl + c来中断进程,那将导致不调用delete并发生内存泄漏。

我该怎么做才能避免这种情况?

此外,如果操作系统回收了内存,那么打开的文件呢? 它们是由操作系统关闭还是我应该手动关闭它们?

在基于虚拟内存的系统中,无论是否在应用程序代码中明确释放进程,都会在进程终止时将所有内存返回给操作系统。 但是,对于其他资源而言,情况可能并非如此,您可能希望干净利落地享受这些资源。 在这种情况下,您需要为SIGINT信号(在Ctrl + C上接收)提供自定义信号处理程序,请参阅例如http://linux.die.net/man/2/sigaction 。

Ctrl C将向进程发送一个SIGINT ,默认情况下会进行大部分有序的关闭,包括拆除内存管理器并释放所有已分配的堆和堆栈。 如果您需要执行其他任务,则需要安装SIGINT处理程序并自行执行这些任务。

当在Linux控制台中按下CTRL + C时,SIGINT信号被发送到应用程序,如果信号没有处理程序,它将终止程序,将所有内存返回给操作系统。 这当然会使得释放内存毫无意义,因为一旦程序存在,所有内存都将被释放。 但是,如果您想处理CTRL + C SIGINT信号(可能将最后一些数据写入文件或进行其他清理),您可以使用函数signal()来安装函数,以便在信号时调用收到了。 如果您想了解更多信息,请查看此function的手册页。

如果您使用shmget(2)分配了任何SYSV共享内存段,则必须使用shmctl(2)清理。

如果您使用shm_open(3)分配了任何POSIX共享内存段,则必须使用shm_unlink(3)清理。

SYSV和POSIX共享内存段都会在进程终止后持续存在。 您可以使用ipcs(1)工具查看持续存在的内容。

当然,如果你没有使用任何SYSV或POSIX共享内存段,那么这只是噪音。 🙂

如果进程退出,通常不会发生内存泄漏。

您分配的大部分内存将在Ctrl + C上释放。 如果您发现内存使用率未返回其先前级别,则几乎可以肯定是由缓冲的文件系统块引起的。

但是,您应该清理一下,特别是如果您使用过任何其他类型的资源:

  • 临时目录中创建的文件不会被删除。 这包括/ dev / shm,留下这样的文件可能被认为是“内存泄漏”。
  • 当您的进程退出时,系统V或posix共享内存段不会被丢弃。 如果这困扰你,请特别清理它们。 或者,在随后的运行中清理它们。

通常,如果后续运行不会泄漏更多内存,则(持久性或半持久性对象(例如文件)的泄漏无关紧要)。 因此,清理未来的运行就足够了。

想象一下从“cron”开始每隔5分钟运行一个进程,如果它在每次运行时崩溃并留下一些混乱,它仍然可以提供每次运行清除前一次崩溃的混乱。

当进程因Ctrl-C或任何其他方式退出时,操作系统将回收进程分配的内存。

您正在订阅一个相当常见的误解,即未被释放但在程序存在时仍可访问的堆块是泄漏。 这不是真的。 泄漏的块是没有指针仍然引用的块,因此它们不能被释放。

通过多年来使用(并打破)许多非常好的内核,我从未设法将虚拟内存管理器充分破坏到一旦退出就不再回收进程的整个地址空间的程度。 除非您正在使用明确标记为“新实验”的内核,否则您将获得更好的运气,而不是找到不使用有效虚拟内存管理器的系统。

为了在Valgrind中获得满分,请不要在代码中添加任何内容。 如果除了释放仍然具有有效引用的内存之外没有其他正常的清理任务,则无需费心。 如果有人向你的程序抛出kill -9 ,你将无法处理它并且会看到旧的行为重复。

如果你有要清理的文件描述符,要放弃的共享锁,要刷新的流或其他任何必须发生的事情,以便其他进程在你离开时不会错过你,一定要注意这一点。 只是不要添加无法解决非问题的代码,这样做似乎很愚蠢。

注意

这本来是一个评论,但是太久了,所以一次写一篇小说的评论也不屑一顾。