Linux C编程 打开目录后,不使用closedir()函数,会有什么样的影响?

在这里插入图片描述

翻博客的时候看到一个有意思的问题,所以就手动研究一下这个问题,
我觉得这个问题中描述的情况会导致内存泄漏内存泄漏是什么

(系统是Ubuntu 18.04的,可以直接去/usr/include找头文件中的定义)
1.
保险起见,我觉得应该去dirent.h看一看,毕竟函数是在这里定义的
嗯,opendir()会返回一个目录流

在这里插入图片描述
2.
再看看closedir()
在这里插入图片描述
3.
从函数声明以及头文件的注释这里并没有看到什么,
想起以前软工的学长给我推荐的一个检查内存泄露的分析工具Valgrind(Linux性能分析工具Valgrid),不妨拿出来玩一玩。

手头有一个现成的程序,我把其中的closedir()注释掉(line74),然后用valgrind检查.

#include <stdio.h>          //perror()
#include <stdlib.h>
#include <string.h>
#include <errno.h>          //strerror()
#include <sys/types.h>      //opendir(),readdir() ,struct stat
#include <dirent.h>         //opendir(), readdir()
#include <sys/stat.h>       //struct stat , stat()
#include <unistd.h>        //stat()

//如果DEBUG为true,则输出函数名称和行号,然后输出您想要打印的内容
//注意  这个报错宏并不会退出进程,你可以使用exit(-1) 来手动退出进程
int DEBUG=1;
#define DBGLOG(format, ...) if(DEBUG){ fprintf(stderr, "%s -- %d -- ", __FUNCTION__, __LINE__); fprintf(stderr, format, ##__VA_ARGS__);}


void do_ls(char* dirname);          //访问各个目录
void do_stat(char* filename);       //获取各个文件信息
void show_file_info(char * filename,struct stat *file_info);//展示单个文件的信息

int main(int argc,char **argv)
{
    if(argc==1){

        do_ls(".");

    }else {

    while(argc=argc-1){
        printf("%s:\n",*++argv);
        chdir(*argv);       //切换工作目录到对应的路径 如果argv并非是目录文件,也可以这么做
        do_ls(*argv);
        chdir("");          //切换工作目录到当前目录 这一步是必要的吗
    }

    }

    return 0;
}

void do_ls(char* dirname){//访问各个目录

    DIR * dir_ptr;
    struct dirent *dirent_ptr;
    /********************************
    struct dirent
    {
       long d_ino;                  //inode number 索引节点号
       off_t d_off;                 //offset to this dirent 在目录文件中的偏移
       unsigned short d_reclen;     //length of this d_name 文件名长
       unsigned char d_type;        //the type of d_name 文件类型
       char d_name [NAME_MAX+1];    //file name (null-terminated) 文件名,最长255字符
    }
    ********************************/

    if( (dir_ptr=opendir(dirname))==NULL ){

            //如果不是目录文件,就会报错,并且直接进行do-stat()处理
            DBGLOG("Cannot open %s , not a directory, treat as a file shown below:\n",dirname);
            //这里并不退出进程 ,因为在ls命令中实参可以使用文件名
            do_stat(dirname);

    }else{  //是目录文件,需要用readdir()

        while( (dirent_ptr=readdir(dir_ptr))!=NULL ){

            do_stat(dirent_ptr->d_name);

        }



    }

  // if( closedir(dir_ptr)==-1 ){    //关闭目录句柄失败

        //DBGLOG("Closedir %s Error: %s\n",dirname,strerror(errno));
  //
        //exit(-1);
  //  }

}

void do_stat(char* filename){//获取各个文件信息

    struct stat file_info;
    /********************************
    struct stat {

        mode_t     st_mode;       //文件对应的模式,文件,目录等

        ino_t      st_ino;       //inode节点号

        dev_t      st_dev;        //设备号码

        dev_t      st_rdev;       //特殊设备号码

        nlink_t    st_nlink;      //文件的连接数

        uid_t      st_uid;        //文件所有者

        gid_t      st_gid;        //文件所有者对应的组

        off_t      st_size;       //普通文件,对应的文件字节数

        time_t     st_atime;      //文件最后被访问的时间

        time_t     st_mtime;      //文件内容最后被修改的时间

        time_t     st_ctime;      //文件状态改变时间

        blksize_t st_blksize;    //文件内容对应的块大小

        blkcnt_t   st_blocks;     //伟建内容对应的块数量

      };
    ********************************/

    if( stat(filename,&file_info)==-1 ){//读文件信息失败

        DBGLOG("Get %s file_info error \n",filename);

        exit(-1);


    }else{//读文件信息成功

        show_file_info(filename,&file_info);

    }



}

void show_file_info(char * filename,struct stat *file_info){//展示单个文件的信息

    printf("show_file_info: %s ;\n",filename);

}


用valgrind检查以下有没有内存泄露

在这里插入图片描述

好家伙,直接内存泄漏32,816字节,就因为没有用closedir()关掉DIR流


版权声明:本文为qq_43103778原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。