• 关于内存泄漏的经典面试题


    目录

     前言

    一、内存泄漏基本概念 

    二、如何判断并查找内存泄漏

    1、方案设计

    2、方案实现


     前言

            对于C/C++程序员来说,或多或少都会被面试官问到关于内存泄漏的问题,内存泄漏是程序的bug,他会一点一点的侵蚀你的内存,导致程序运行一段时间后会莫名崩溃,本文就主要讲解如何不使用工具来查找内存泄漏的问题;

    一、内存泄漏基本概念 

            所谓内存泄漏,一般是调用了类似malloc、realloc 等在堆空间申请内存的函数,当我们在使用完以后未释放申请的空间便会导致内存泄漏,下面是一段经典的内存泄漏代码;

            我们尝试对如下代码编译链接并执行,如下图所示;

            我们发现与正常程序执行并无差别,也没有报错相关信息,我们无法的得知是否有内存泄漏相关问题,于是我们有了如下想法;

    二、如何判断并查找内存泄漏

    1、方案设计

            关于内存泄漏程序,我们并没有能力能看出是否内存泄漏,如上述程序,我们得设计一个方案,首先能排查出这个程序是否有内存泄漏,其次我们也要找到内存泄漏的位置;这样才是一个合格的方案;

    思路:我们对malloc函数 “重写” ,在申请内存前,首先申请空间,然后再创建一个文件,文件内容是在何处调用这个malloc函数,接着我们也对 free 函数完成 “重写” ,我们在free函数删除这个文件;在程序运行结束后,我们可以通过是否还有我们因malloc创建的文件判断是否发生了内存泄漏的问题;

    2、方案实现

            下面就是方案实现代码;代码的核心在main函数上面的代码,这段代码仅仅作用于单文件的内存泄漏的查找;

    1. #include
    2. #include
    3. #include
    4. #include
    5. // malloc 函数重写
    6. // 第一个参数为申请大小,第二个参数为文件名,第三个参数为行号
    7. void* _malloc(size_t size, const char* file, int line)
    8. {
    9. // 文件内容
    10. char buf[128] = { 0 };
    11. // 文件名
    12. char filename[128] = "./memfile/"; // 当前目录的memfile目录保存所有文件
    13. char tmp[128] = { 0 };
    14. // 调用malloc申请内存
    15. void* p = malloc(size);
    16. // 生成对应内容
    17. sprintf(buf, "memLeak-%p-%s-%d", p, file, line);
    18. sprintf(tmp, "%p", p);
    19. strcat(filename, tmp);
    20. // 打开文件
    21. FILE* pf = fopen(filename, "w");
    22. // 写入操作
    23. fwrite(buf, 1, strlen(buf), pf);
    24. // 关闭文件
    25. fclose(pf);
    26. pf = NULL;
    27. return p;
    28. }
    29. // free 函数重写
    30. void _free(void* p)
    31. {
    32. char buf[128] = "./memfile/";
    33. char tmp[128] = { 0 };
    34. sprintf(tmp, "%p", p);
    35. strcat(buf, tmp);
    36. if(unlink(buf) < 0) // unlink函数为删除文件的函数
    37. {
    38. // 这个文件被free了两次
    39. printf("free 重复调用");
    40. return ;
    41. }
    42. free(p);
    43. }
    44. // 这里的宏定义切记不可写在上面的重写函数之上,不然会循环调用
    45. #define malloc(N) _malloc(N, __FILE__, __LINE__)
    46. #define free(p) _free(p)
    47. int main()
    48. {
    49. void* p1 = malloc(10);
    50. void* p2 = malloc(20);
    51. free(p1);
    52. return 0;
    53. }

            我们运行上述代码,确实发现了memfile目录下有一个文件;如下所示;

            我们打开这个文件,查看内容;

            在memeryLeak.c文件下的54行确实就是没有释放的 malloc 函数;

  • 相关阅读:
    安装Vue前的环境配置
    VALSE2022内容总结
    怎样下载视频号视频?分享6种有效方法
    【文末送书——数学经典著作】工科必备的数学思维培养
    【BOOST C++】高级01 RAII和内存管理
    (十五)Spring之面向切面编程AOP
    Unity之Hololens如何实现传送功能
    服务器数据恢复-服务器硬盘指示灯黄灯闪烁的数据恢复案例
    【应用】Docker
    静态时序分析:保持时间分析
  • 原文地址:https://blog.csdn.net/Nice_W/article/details/134062560