多年来我一直避免尝试使用operator new做任何事情,因为我觉得它在Windows上是一个泥潭(特别是使用MFC).更不用说,除非有一个非常令人信服的理由混淆全局(甚至是类)新的和删除,否则不应该.
但是,我有一个讨厌的小内存损坏错误,我非常想跟踪它.我从CRT调试分配器获取消息,指示先前释放的内存被覆盖.此消息仅在稍后的分配调用期间显示,当它尝试重用块时(无论如何,我相信这是它的工作原理).
由于有问题的代码部分,错误消息和损坏点是非常不相关的.我所知道的是"某个地方覆盖了一些以前用一个空字节释放的内存." (我通过使用调试器并在几个不同的运行中观察调试堆引用的内存来确定这一点).
已经用尽了关于罪魁祸首的明显想法,我不得不尝试做一些更严谨的事情.在我看来,如果我可以使每个释放的块成为一个无访问的内存页面,那么编写器将立即被CPU的MMC捕获,这将是理想的!稍后再进行一些搜索,我发现有人在这些方面实现了一些东西:
http://www.codeproject.com/Articles/38340/Immediate-memory-corruption-detection
他的代码被埋没在大量的重新编码代码中,但提取核心概念非常简单,我已经这样做了.
我现在遇到的问题是MFC将新的redfines重新定义为DEBUG_NEW,然后进一步定义了一系列调试接口,直到CRT.此外,它确实定义了全局运算符new和delete.因此,就C++而言,"用户"试图将全局运算符new和delete替换为两次,因此我得到了一个链接器错误,其效果为'已定义的符号'.
环顾互联网,以及SO,我看到了一些有前途的文章,但没有一个最终对于替换MFC的全局运营商new/delete有任何积极意义.
如何正确替换全局new和delete运算符
是否可以在MFC应用程序的调试版本中替换内存分配器?
我已经知道了:
好吧,它提供了它提供的功能 - 比如让我首先沿着这条路走下去的信息.我现在知道腐败正在发生,但这非常糟糕!
我想提供的是保护分配(或者甚至只是保护重新分配).这显然可以通过使用大量虚拟地址空间并将每个分配隔离开来,这极大地浪费了内存.好吧,是的,当这是一个仅用于调试的代码时,无法看到它的缺点,就像现在这样的特殊用途时刻一样.
所以,我正在拼命寻求以下解决方案
有没有人知道答案,或者阅读的好文章可能会说明如何实现这些目标?
其他想法:
进一步的调查:
2012年5月3日更新:
有什么用的malloc,并free当我们有new和deleteC++中.我想这两个功能free和delete是一样的.
void newHandler() {
cdebug << "memory allocation failure" << std::endl;
throw std::bad_alloc();
}
int main() {
std::set_new_handler(newHandler);
// ...
}
Run Code Online (Sandbox Code Playgroud)
一旦newHandler被建立为我们的错误处理程序,它将在任何堆分配失败时被调用.关于错误处理程序的有趣之处在于它会被连续调用,直到内存分配成功,或者函数抛出错误.
我对上面文本的问题是,"直到内存分配成功,或者函数抛出错误"时,authore的意思是什么.在这种情况下,函数如何抛出错误?要求举例说明.
谢谢你的时间和帮助.
以下是我的应用程序的上下文:我正在使用嵌入式系统,该系统使用来自不同设备的RAM.微控制器内部RAM(128kB)中的一部分是外部RAM(1MB).这些存储器映射到微控制器的地址空间,但是在非连续区域中.
内部RAM用于系统堆栈,任务堆栈和堆.外部RAM用于静态分配的数据(池,缓冲区和所有" static ..."内容)
我正在尝试实现一个简单的内存管理结构,并且作为其中的一部分能够创建一个分配器,它可以使用分配算法,operator new但使用另一个内存源,而不是系统堆,而是其他地方的内存区域.你知道这是否可行?
使用的一个示例可以是保留100kB的外部RAM并创建一个分配器来管理它,然后将其分配给需要该内存的指定任务.
static const uint8_t* ramBase = reinterpret_cast<uint8_t*>(0x80000000);
static const uint32_t ramAreaSize = 0x19000; //100kB
BufferAllocator allocator(ramBase, ramAreaSize);
//...
//Assuming operator new is overloaded to use BufferAllocator
MyObject * obj = new (allocator) MyObject(some, parameter);
//...
Run Code Online (Sandbox Code Playgroud)
问题是:如何(如果这是可能的话)我可以实现BufferAllocator以便operator new用来管理原始内存区域?
void* BufferAllocator::allocate(uint32_t bytes)
{
//I would like to write something like this
//and so let the responsibility to manage this memory area to "new"
//so I don't have to reimplement …Run Code Online (Sandbox Code Playgroud) 给出以下代码:
int i;
...
ostingstream os;
os<<i;
string s=os.str();
Run Code Online (Sandbox Code Playgroud)
我想用ostringstream这种方式计算动态内存分配的次数.我怎样才能做到这一点?也许通过operator new?
谢谢.
我遇到了一个小的标准头文件<new>。我以前可能没有见过它的直接使用。这是g++ 版本,供感兴趣的人参考。
以下部分是我感兴趣的:
struct nothrow_t { };
extern const nothrow_t nothrow;
/** If you write your own error handler to be called by @c new, it must
* be of this type. */
typedef void (*new_handler)();
/// Takes a replacement handler as the argument, returns the previous handler.
new_handler set_new_handler(new_handler) throw();
Run Code Online (Sandbox Code Playgroud)
struct nothrow_t它及其对象?nothrow该对象真的需要吗extern?new_handler用的?operator new/delete在块中声明extern C++?我正在阅读"Thinking in c ++"的第13章.以下内容来自本书.
MyType*fp = new MyType(1,2);
在运行时,调用malloc(sizeof(MyType))的等价物,并使用(1,2)作为参数列表调用MyType的构造函数,并将结果地址作为this指针.到指针指向fp时.
我对这句大胆的句子感到困惑.这是什么意思?
这是运营商new的伪代码:
while (true)
{
Attempt to allocate size bytes
if (the allocation was successful)
return (a pointer to the memory);
// The allocation was unsuccessful; find out what the
// current new-handling function is
new_handler globalHandler = set_new_handler(0);
set_new_handler(globalHandler);
if (globalHandler)
(*globalHandler)();
else
throw std::bad_alloc();
}
Run Code Online (Sandbox Code Playgroud)
问题:
1)为什么第一次将0作为参数传递给set_new_handler函数?
2)它表示当分配失败时,调用new_handler函数,尝试分配momory,当且仅当不能产生更多内存时,它返回指向已分配内存的开始的指针,或者如果它不能,则抛出bad_alloc exeption或返回空指针并且else body工作,抛出bad_alloc exeption.我的问题是为什么new_handler函数有时抛出exeption,如果它可以返回空指针,否则body会这样做?
我对移动语义的直觉是对象字段的浅层复制,然后可能是对旧 r 值的一些破坏。然而,据我所知,当某些字段拥有指针/引用时,只有浅拷贝/深拷贝存在差异。如果您根本不使用堆,所以没有mallocor new,那么您可能不会有拥有指针的类/结构。因此,移动构造函数与常规复制构造函数没有任何区别。我的逻辑正确吗?
是否可以覆盖 STL 分配、管理和释放内存的方式?如果可能的话,怎么做呢?有没有一种方法可以将处理原始内存的代码保留在一个类或文件中?
我想为我的整个程序执行此操作,以便我可以跟踪内存使用情况、时间和生命周期信息。当然纯粹是出于好奇!
假设我有一个A类,我在类中重载operator new.
class A{
public:
A();
void *operator new(size_t size);
void operator delete(void *p);
}
Run Code Online (Sandbox Code Playgroud)
我如何在A类中使用这个重载的operator new而不是全局new?例如
A::A(){
...
int *temp = new int[10]; //Use overloaded new and not global new
}
Run Code Online (Sandbox Code Playgroud)
我环顾四周,我认为我没有看到一个解决这个问题的问题.
谢谢!
c++ ×11
new-operator ×2
embedded ×1
heap-memory ×1
memory ×1
memory-leaks ×1
mfc ×1
move ×1
nothrow ×1
std ×1
stl ×1