视觉C++新建、删除、新建 [] 和删除 []
visual C++ new, delete, new[] and delete[]
我目前正在开发自己的内存泄漏跟踪系统。
我正在使用 2008 Microsoft Visual C++,我知道他们有一个内置的,但我一直在为自己制作一个,只是为了好玩。
但是,当我覆盖 new 和 new[] 命令时,无论我做什么,我都会收到函数重定义错误。
我对Visual C++Microsoft的内部绑定了解不多,但我听说CRT已经定义了与我完全相同的宏。
我在这里和其他地方看到过针对同一确切问题的文章,但是人们似乎永远无法解决问题,或者永远不会给出明确的答案解决了。
以下是到目前为止我拥有的所有代码:
MLD.h : http://pastebin.com/SfHzNaeNMLD.cpp : http://pastebin.com/aRhsTZpv
所有代码都松散地基于旧的翻码文章(如何检测内存泄漏(。抱歉,我无法为您提供直接链接,因为我没有 10 个代表来发布超过 2 个超链接。
谢谢你的时间。
"函数重定义错误"可能是因为您使用的是 MFC。
运行时库不应参与定义此类分配和释放函数的业务。
当前代码的
struct MemLeakInfo
{
unsigned int addr;
unsigned int line;
unsigned int size;
unsigned char file;
};
不好。不能保证unsigned int
足够大以容纳地址,即使它位于 32 位 Windows 中也是如此。请改用 intptr_t
。
此外,当前代码的
void* operator new(unsigned int Size, int Line, const char* File);
不好。那应该是...
void* operator new( size_t Size, int Line, const char* File );
并且您需要相应的operator delete
,例如...
void* operator delete( void* p, int Line, const char* File );
为了从失败的构造函数调用中释放内存。它只在非常特殊的情况下被调用。但是,如果您没有它,那么您就会有泄漏,就像 MFC 曾经用于调试版本一样。
编辑:您现在提供的代码的固定版本:
文件 [最小.h]:
-
_MINIMAL_H
无效,因为它以下划线开头,后跟大写字母,这是保留的。更改为MINIMAL_H
。 - 要使用
size_t
您需要包含<stddef.h>
。 -
_DEBUG
不是标准的宏。 这是一种微软主义。 用于此目的的标准宏(查找assert
的文档(是NDEBUG
。
#ifndef MINIMAL_H
#define MINIMAL_H
#include <stddef.h> // std::size_t
#ifndef NDEBUG
void* operator new( size_t Size, int Line, const char* File );
void* operator new[]( size_t Size, int Line, const char* File );
void operator delete( void* ptr, int Line, const char* File );
void operator delete[]( void* ptr, int Line, const char* File );
#endif
#ifndef NDEBUG
#define DEBUG_NEW new( __LINE__, __FILE__ )
#else
#define DEBUG_NEW new
#endif
#endif //MINIMAL_H
文件 [最小.cpp]:
- 要使用
malloc
您需要包含stdlib.h
。 - 当您
#define new
时,您将对以下代码中的new
关键字造成严重破坏。 - 在 C 语言中,你永远不应该投射
malloc
的结果,而在 C++ 中,你只应该在需要的时候投射一些东西。 这里没有这样的需要。 只投射掩码错误,这不是一个好主意。
错误 - 情况下缺少返回。对于错误,您需要
throw std::bad_alloc
. 这是根据神圣标准对这些函数的规范。
#include "Minimal.h"
//#define new DEBUG_NEW
#ifndef NDEBUG
#include <stdlib.h> // malloc
#include <exception> // std::bad_alloc
void* operator new( size_t const size, int, const char*)
{
void* const ptr = malloc( size );
if( !ptr ) { throw std::bad_alloc(); }
return ptr;
};
void* operator new[]( size_t const size, int, const char*)
{
void* const ptr = malloc( size );
if( !ptr ) { throw std::bad_alloc(); }
return ptr;
}
void operator delete(void* const ptr, int, const char*)
{
free( ptr );
};
void operator delete[]( void* const ptr, int, const char* )
{
free( ptr );
};
#endif
相关文章:
- 创建模板类型而不新建/删除
- C++ 在请求特定字节的新建后删除
- 为什么非放置"新建"和"删除"内置于语言中,而不仅仅是常规函数?
- 来自C#的mingw DLL:为什么我必须覆盖新建/删除?
- C++ - 定义自定义新建和删除运算符时make_shared
- 使用安全零内存新建/删除时出现问题
- 奇怪的内存泄漏由C++中的新建/删除
- CRT 检测到应用程序在堆缓冲区(新建/删除)类结束后写入内存
- 无法覆盖C++中纯抽象类中的运算符删除/新建
- 编译器或标准C++库 - 新建和删除
- 混合运算符和表达式新建/删除
- 新建和删除的经验法则
- 运算符新建和删除重载作用域
- 使用运算符重载(新建/删除)实现单例的优缺点
- 忽略全局覆盖的新建/删除
- C++内存泄漏新建并删除
- 基本的新建/删除操作员日志记录
- C++自定义全局新建/删除覆盖系统库
- 为什么使用XXXX_new和XXXX_free而不是新建和删除
- 新建和删除如何工作以及它们的存储位置