分享一个重载new、new[],打印日志的东西

CZURCommon.h

C/C++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

#ifndef _CZUR_COMMON_H

#define _CZUR_COMMON_H

 

#include "windows.h"

#include <iostream>

 

class CZURLog

{

public:

    CZURLog();

    virtual ~CZURLog();

 

    void CreateLogFile(LPCSTR lpszLogName);

    void PrintLog(char *pFormat, ...);

 

public:

    FILE            *m_pLogFile;

    CRITICAL_SECTION m_csLog;

};

 

class CZURMutex

{

public:

    CZURMutex(CRITICAL_SECTION *pcsLog);

    virtual ~CZURMutex();

 

private:

    CRITICAL_SECTION *m_pcsLog;

};

 

 

//变量声明

extern CZURLog g_OutLog;

 

void *operator new(size_t size, LPCSTR lpszFileName, int line);

 

void *operator new[](size_t count, LPCSTR lpszFileName, int line);

 

 

 

#endif    //_CZUR_COMMON_H



CZURCommon.cpp

C/C++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

#include "CZURCommon.h"

 

CZURLog g_OutLog;

 

CZURLog::CZURLog()

    :m_pLogFile(NULL)

{

    InitializeCriticalSection(&m_csLog);

}

 

CZURLog::~CZURLog()

{

    if(m_pLogFile)

    {

        fclose(m_pLogFile);

    }

    DeleteCriticalSection(&m_csLog);

}

 

void CZURLog::CreateLogFile(LPCSTR lpszLogName)

{

    if(lpszLogName)

    {

        m_pLogFile = fopen(lpszLogName, "at+");

    }

}

 

void CZURLog::PrintLog(char *pFormat, ...)

{

    char    szString[1024];

    va_list args;

 

    va_start(args, pFormat);

    vsprintf(szString, pFormat, args);

    va_end(args);

 

    //获取系统时间

    SYSTEMTIME sysTime;

    GetLocalTime(&sysTime);

 

    char szLogText[1024];

    //格式化本地时间

    sprintf_s(

        szLogText, 1024, "[%4d-%02d-%02d %02d:%02d:%02d] %s\n"

        sysTime.wYear, sysTime.wMonth, sysTime.wDay,

        sysTime.wHour, sysTime.wMinute, sysTime.wSecond,

        szString

    );

 

    CZURMutex mutex(&m_csLog);

 

    if(m_pLogFile)

    {

        fseek(m_pLogFile, 0, SEEK_END);

        fputs(szLogText, m_pLogFile);

        fflush(m_pLogFile);

    }

}

 

CZURMutex::CZURMutex(CRITICAL_SECTION *pcsLog)

{

    m_pcsLog = pcsLog;

    EnterCriticalSection(pcsLog);

}

 

CZURMutex::~CZURMutex()

{

    LeaveCriticalSection(m_pcsLog);

}

 

void *operator new(size_t size, LPCSTR lpszFileName, int line)

{

    void *ptr = NULL;

    try

    {

        ptr = ::operator new(size);

    }

    catch(std::bad_alloc)

    {

        g_OutLog.PrintLog("FILE: %s, LINE: %d, Error: Memory Allocation Failed", lpszFileName, line);

    }

    return ptr;

}

 

void *operator new[](size_t count, LPCSTR lpszFileName, int line)

{

    return operator new(count, lpszFileName, line);

}



附带测试Test.cpp说明:

C/C++ code?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

/*

 

关于重载new、new[]的使用说明

 

在工程中,包含CZURCommon.h、CZURCommon.cpp文件

 

在需要使用重载的new、new[]运算符的cpp文件中,添加#include "CZURCommon.h",

 

并宏定义:#define new new(__FILE__, __LINE__)

(宏定义new目的,简化调用时的繁琐,将重载的new、new[]用起来和之前的new、new[]没有任何区别,

如果不进行宏定义,则调用方式:int *p = new(__FILE__, __LINE__) int[2])

 

程序运行之初,调用g_OutLog.CreateLogFile()函数,创建日志文件

 

如是,调用new、new[]分配内存失败的时候,捕获异常,在日志中输出相应的错误信息

 

*/

 

#include "CZURCommon.h"

#include "stdio.h"

 

//宏定义new运算符

#define new new(__FILE__, __LINE__)

 

int main()

{

    //设置日志文件名称

    g_OutLog.CreateLogFile("d:\\1.log");

 

    //为了测试,循环申请内存,不释放

    while(1)

    {

        char *p = new char;

 

        //内存分配失败,在D盘中的error.log中输出错误信息

        if(NULL == p)

        {

            printf("内存分配失败,请查看日志信息\n");

            return 0;

        }

    }

    system("pause");

 

    return 0;

}



说明:打印log信息部分,之前的做法是每次都打开log文件,写入后,关闭log文件,但测试发现,对于new、new[]失败时,调用fopen打开log文件会失败(猜测原因:fopen内部会申请堆内存,而此时堆内存不足,导致失败),因此无法将new、new[]错误信息正常写入到log文件中,针对这种情况,改进了做法,程序运行之初,创建log文件,运行结束后,关闭log文件,确保所有的log信息不会因为new、new[]失败而丢失。

转载于:https://my.oschina.net/u/4000302/blog/3083657

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值