首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在crtdbg.h引起冲突时重写C++中的新运算符

在crtdbg.h引起冲突时重写C++中的新运算符
EN

Stack Overflow用户
提问于 2011-02-19 20:41:22
回答 4查看 10.7K关注 0票数 4

在为我自己的内存管理器尝试一些内存跟踪和准备时,我试图重写新的操作符。关于反编译码的文章是我在这个过程( Leaks.shtml )中的主要指导方针。

在实现了本文中描述的技术之后,我遇到的问题是,在STL中的某个地方,"crtdbg.h“直接或间接地通过正在包含的一些头文件(使用Visual 2010)被包含。

这将导致一个错误:

代码语言:javascript
复制
[...]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文件插入的。

代码语言:javascript
复制
// The header files that should be included for using the CrtDumpMemoryLeaks:
//#define _CRTDBG_MAP_ALLOC
//#include <stdlib.h>
//#include <crtdbg.h>
//...
_CrtDumpMemoryLeaks()

撇开这是一个好主意,或者不实现我自己的新/删除,我想知道如何才能有我自己的新/删除实现,同时仍然使用一些标准的库功能,并且没有这些重新定义错误。

代码如下所示:

memdebug.h

代码语言:javascript
复制
#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

#endif

memdebug.c

代码语言:javascript
复制
#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 );
}
#endif

main.cpp

代码语言:javascript
复制
#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文件)之后才这样做很麻烦。

我相信,这只能通过为新操作符使用自定义名称来解决,并使用该名称。我说的对吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-20 13:17:33

好吧,我现在解决这个问题的方式,不需要使用自定义的“新”定义,就是我已经创建了一个通用的头文件,比方说“Engine.h”,它包含在每个文件中。这可以通过在项目设置中使用强制包含文件来实现,/配置属性/ C/C++ /高级

此文件包含#define (从mem调试器h中删除)

engine.h

代码语言:javascript
复制
#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")。

请注意,当使用第三方库时,重写新操作符仍然是有风险的,而第三方库可能也会这样做。这将导致使用此处使用的模式重写这些文件的新操作符。在这种情况下,您可能需要重新考虑自定义新定义的用法,如下所示:

代码语言:javascript
复制
#define myNew new(__FILE__, __LINE__)

(在Leaks.shtml中也有描述)

票数 3
EN

Stack Overflow用户

发布于 2011-02-19 22:23:33

在我们的一个应用程序中,我们诉诸于在应用程序级别将所有地方重命名为new,使用xnew,然后将调试宏定义为仅在xnew上运行。

使用new并将其重新定义为宏也会给自定义分配器带来问题。不幸的是,用于分配的C++语法增加了调试包装器的难度。

票数 2
EN

Stack Overflow用户

发布于 2013-03-27 18:42:12

在Visual 2010上,我能够做到这一点,而无需重新定义新的或自定义的new。我创建了一个具有以下内容的头文件:

代码语言:javascript
复制
#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++ /预处理器中获得。

希望这能在这个问题上有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5053382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档