在为我自己的内存管理器尝试一些内存跟踪和准备时,我试图重写新的操作符。关于反编译码的文章是我在这个过程( Leaks.shtml )中的主要指导方针。
在实现了本文中描述的技术之后,我遇到的问题是,在STL中的某个地方,"crtdbg.h“直接或间接地通过正在包含的一些头文件(使用Visual 2010)被包含。
这将导致一个错误:
[...]10.0\vc\include\crtdbg.h(1078): error C2365: 'operator new' : redefinition; previous definition was 'function'
[...]10.0\vc\include\crtdbg.h(1078): error C2078: too many initializers
[...]通过在没有包含头文件的情况下放置'_CrtDumpMemoryLeaks()‘进行快速检查,证实了我的怀疑,即头文件确实是通过STL文件插入的。
// The header files that should be included for using the CrtDumpMemoryLeaks:
//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>
//...
_CrtDumpMemoryLeaks()撇开这是一个好主意,或者不实现我自己的新/删除,我想知道如何才能有我自己的新/删除实现,同时仍然使用一些标准的库功能,并且没有这些重新定义错误。
代码如下所示:
memdebug.h
#ifndef _MEM_DEBUG_H
#define _MEM_DEBUG_H
#ifdef _DEBUG
void * operator new( unsigned int size, const char *filename, int line );
void operator delete( void *ptr );
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
#endif
#endifmemdebug.c
#ifdef _DEBUG
void * operator new( unsigned int size, const char *filename, int line )
{
void *ptr = (void *)malloc(size);
//AddTrack((DWORD)ptr, size, filename, line);
return(ptr);
};
void operator delete( void *ptr )
{
//RemoveTrack( (DWORD)ptr );
free( ptr );
}
#endifmain.cpp
#include "memdebug.h"
#include <iostream>
void main()
{
Test *pTest = new Test();
std::cout << "end" << std::endl;
}我解决这个问题的方法是将#define new DEBUG_NEW移到<iostream>下面;问题已经解决了,因为它不会在crtdbg.h中重写新的文件;然而,这确实使必须确保总是在可能的头部(包括crtdbg.h文件)之后才这样做很麻烦。
我相信,这只能通过为新操作符使用自定义名称来解决,并使用该名称。我说的对吗?
发布于 2011-02-20 13:17:33
好吧,我现在解决这个问题的方式,不需要使用自定义的“新”定义,就是我已经创建了一个通用的头文件,比方说“Engine.h”,它包含在每个文件中。这可以通过在项目设置中使用强制包含文件来实现,/配置属性/ C/C++ /高级。
此文件包含#define (从mem调试器h中删除)
engine.h
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <windows.h>
#include "MemoryNappy.h"
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW这将强制系统在自定义新定义之前考虑crtdbg.h,并且不会在那里更改新的。当它第二次包含在某一行的某个地方时,它只是使用已经加载过的数据。(在包含<iostream>之后包含"engine.h")。
请注意,当使用第三方库时,重写新操作符仍然是有风险的,而第三方库可能也会这样做。这将导致使用此处使用的模式重写这些文件的新操作符。在这种情况下,您可能需要重新考虑自定义新定义的用法,如下所示:
#define myNew new(__FILE__, __LINE__)(在Leaks.shtml中也有描述)
发布于 2011-02-19 22:23:33
在我们的一个应用程序中,我们诉诸于在应用程序级别将所有地方重命名为new,使用xnew,然后将调试宏定义为仅在xnew上运行。
使用new并将其重新定义为宏也会给自定义分配器带来问题。不幸的是,用于分配的C++语法增加了调试包装器的难度。
发布于 2013-03-27 18:42:12
在Visual 2010上,我能够做到这一点,而无需重新定义新的或自定义的new。我创建了一个具有以下内容的头文件:
#pragma once
//_CRTDBG_MAP_ALLOC
//_CRTDBG_MAP_ALLOC_NEW
#define _CRTDBG_MAP_ALLOC
#define _CRTDBG_MAP_ALLOC_NEW
#include <stdlib.h>
#include <crtdbg.h>并强制将其包含在每个源文件中,在项目设置/配置属性/ C/C++ /高级中使用已经讨论过的选项“强制包含文件”。实际上,crtdbg.h已经完成了新的自定义定义,以及常规新的未定义。为了确保一切顺利进行,我将_CRTDBG_MAP_ALLOC and_CRTDBG_MAP_ALLOC_NEW添加到预处理器定义列表中,该列表可在:项目设置/配置属性/ C/C++ /预处理器中获得。
希望这能在这个问题上有所帮助。
https://stackoverflow.com/questions/5053382
复制相似问题