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

目录

 前言

一、内存泄漏基本概念 

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

1、方案设计

2、方案实现


 前言

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

一、内存泄漏基本概念 

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

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

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

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

1、方案设计

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

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

2、方案实现

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

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

// malloc 函数重写
// 第一个参数为申请大小,第二个参数为文件名,第三个参数为行号
void* _malloc(size_t size, const char* file, int line)
{
    // 文件内容
    char buf[128] = { 0 };
    // 文件名
    char filename[128] = "./memfile/";  // 当前目录的memfile目录保存所有文件
    char tmp[128] = { 0 };
    // 调用malloc申请内存
    void* p = malloc(size);
    // 生成对应内容
    sprintf(buf, "memLeak-%p-%s-%d", p, file, line);
    sprintf(tmp, "%p", p);
    strcat(filename, tmp);
    // 打开文件
    FILE* pf = fopen(filename, "w");
    // 写入操作
    fwrite(buf, 1, strlen(buf), pf);
    // 关闭文件
    fclose(pf);
    pf = NULL;

    return p;
}
// free 函数重写
void _free(void* p)
{
    char buf[128] = "./memfile/";
    char tmp[128] = { 0 };
    sprintf(tmp, "%p", p);
    strcat(buf, tmp);
    if(unlink(buf) < 0)  // unlink函数为删除文件的函数
    {
        // 这个文件被free了两次
        printf("free 重复调用");
        return ;
    }
    free(p);
}

// 这里的宏定义切记不可写在上面的重写函数之上,不然会循环调用
#define malloc(N) _malloc(N, __FILE__, __LINE__)
#define free(p) _free(p)

int main()
{
    void* p1 = malloc(10);
    void* p2 = malloc(20);

    free(p1);
    return 0;
}

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

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

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

猜你喜欢

转载自blog.csdn.net/Nice_W/article/details/134062560
今日推荐