进程退出以及内存释放

进程退出表示进程即将结束运行。

1.正常退出

  • 在main函数中执行return。
  • 调用exit函数。
  • 调用_exit函数。

2.异常退出

  • 调用abort函数
  • 进程收到某个信号,该信号使程序终止。

进程退出后都会将所有已打开的文件描述符关闭,释放它所占用的内存和其他资源

各种退出方式之间的比较:

  • exit和return:exit是一个函数,有参数;return是函数执行完后的返回。exit把控制权交给系统,return将控制权交给的调用函数。
  • exit和abort:exit是正常终止进程,abort是异常终止。
  • exit(int exit_code):exit中的参数为0代表进程正常终止,若为其他表示程序执行过程有错误发生。
  • exit()和_exit:exit在stdlib.h中声明,而_exit声明在unistd.h中。两函数均表示正常终止进程。但_exit()会执行后立即返回给内核,而exit()要先执行一些清除操作后才将控制权交给 内核。

父子进程终止的先后顺序回产生不同的结果,子进程退出前父进程先退出,则会产生孤儿进程,由init进程接管。当子进程先于父进程终止,而父进程又没有调用wait函数等待子进程结束,子进程就回进入僵死状态,子进程进入僵死状态之后内核只保存该进程的一些必要信息以备父进程所需。若父进程调用了wait或waitpid函数,则父进程会等待子进程结束。

下面这个例子解释了关于退出时的内存释放与否与不同的退出方式之间的联系:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>

int globvar = 5;

int main(void)
{
    pid_t pid;
    int var = 1, i;

    printf("fork is diffirent with vfork\n");

    pid = vfork();
    switch(pid)
    {
        case 0:
        i = 3;
        while(i-- > 0)
        {
            printf("child process is run\n");
            globvar++;
            var++;
            printf("child var = %d\n", var);
            sleep(1);
        }
        printf("child globvar = %d, var = %d\n", globvar, var);
        break;

        case -1:
        perror("parent process failed\n");
        exit(0);

        default:
        i = 5;
        while(i-- > 0)
        {
            printf("parent process is running\n");
            globvar++;
            var++;
            printf(" parent var = %d\n", var);
            sleep(1);
        }
        printf("parent's globvar = %d, var = %d\n", globvar, var);
        exit(0);
    }
}

这段代码本来是要测试vfork创建的子进程与父进程公用同一块内存空间,也就是子进程对变量的改变对父进程是可见的。但最终的结果却出乎意料:
这里写图片描述
当子进程退出之后,父进程本来应当接着子进程的var进行递加的,但是最终的结果却是子进程退出,父进程的var成为了随机值,后来我在程序的最后添加了exit(0)之后程序的执行结果就变成了这样:
这里写图片描述
变量的结果正常了,这是因为在之前case 0时子进程的退出在break之后并未做任何退出函数的调用于是默认是以return结束这个函数的,那么return的退出是函数的退出,函数的退出是会清除在函数内部的局部变量的。所以var值被释放,变成了随机值。当在最后添加exit(0)之后,exit并不会释放栈内存,所以结果正常了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Windows下,可以使用一些工具来检查进程退出前的内存泄漏情况。以下是一些常用的方法: 1. 使用内存泄漏检测工具:可以使用一些专门的内存泄漏检测工具来帮助检测内存泄漏,例如Visual Leak Detector、CRT Debug Heap等。这些工具可以在程序运行时监测内存的分配和释放情况,并提供详细的报告和分析。你可以在代码中添加这些工具的头文件和链接库,并在程序退出调用相应的函数来生成内存泄漏报告。 2. 使用调试器:可以使用调试器(如Visual Studio)来检查进程退出前是否存在内存泄漏。在调试器中启动程序,并在程序退出前进行断点调试。通过观察内存的分配和释放情况,以及查看堆栈信息,可以判断是否存在内存泄漏。 3. 重载全局`operator new`和`operator delete`:可以在代码中重载全局的`operator new`和`operator delete`操作符,以跟踪内存的分配和释放情况。通过记录每个对象的分配和释放,可以在程序退出前检查是否有未释放内存块。 4. 使用性能分析工具:可以使用性能分析工具(如Windows Performance Recorder和Windows Performance Analyzer)来分析进程内存使用情况。通过收集和分析进程内存分配和释放数据,可以检测内存泄漏并找出泄漏的位置。 需要注意的是,以上方法都只能帮助检测和分析内存泄漏的情况,但不能完全消除内存泄漏的可能性。因此,在编写代码时应养成良好的内存管理习惯,并进行适当的测试和验证,以确保程序的内存使用是正确和高效的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值