相关疑难解决方法(0)

如何在MFC应用程序中替换全局运算符new和delete(仅限调试)

多年来我一直避免尝试使用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应用程序的调试版本中替换内存分配器?

我已经知道了:

  • MFC/CRT已经为内存分配提供了丰富的调试工具.

好吧,它提供了它提供的功能 - 比如让我首先沿着这条路走下去的信息.我现在知道腐败正在发生,但这非常糟糕!

我想提供的是保护分配(或者甚至只是保护重新分配).这显然可以通过使用大量虚拟地址空间并将每个分配隔离开来,这极大地浪费了内存.好吧,是的,当这是一个仅用于调试的代码时,无法看到它的缺点,就像现在这样的特殊用途时刻一样.

所以,我正在拼命寻求以下解决方案

  1. 尽管提供了CRT/MFC,但强制编译器与我的全局运算符new/delete保持共存.
  2. 找到另一种方法将MFC/CRT _heap_alloc_dbg链连接到底部,使用我自己的代码代替他们,用于笔的最终分配(即我将通过操作系统的VirtualAlloc/VirtualFree分配为新的和/或提供内存malloc的).

有没有人知道答案,或者阅读的好文章可能会说明如何实现这些目标?

其他想法:

  1. 使用thunk技术在运行时替换CRT的new/delete.
  2. 还有其他一些方法吗?!

进一步的调查:

  • 这篇文章很酷......它为我提供了一种在运行时修补全局新/删除操作符的方法.但是,正如文章所指出的那样,它有点hackish(但是,因为我只需要这个用于调试版本,这不是什么大问题)http://zeuxcg.blogspot.com/2009/03/fighting-against-crt-堆和- winning.html
    • 因此,虽然这是我想要的(一种替换CRT内存分配功能的机制),但这种实现已经过时了,到目前为止,我尝试使其工作已经遇到了无数问题.我觉得它太砍死它最初是为创建的版本,只为一个相对简单的控制台使用(即C,甚至没有C++,并抛弃大部分由微软提供的CRT调试功能).因此,尽管这是一个超酷的想法,最终会花费很多时间来与当前的VS2010开发工作室合作,因此不值得(对我而言).
  • 显然,有这种想法的一个众所周知的版本:http://en.wikipedia.org/wiki/Electric_Fence不幸的是,即使在Windows端口,我发现http://code.google.com/p/electric-fence-win32 /无法正确覆盖CRT,但要求您修改所有源代码以访问电围栏堆分配代码.:(

2012年5月3日更新:

c++ mfc memory-leaks memory-management

6
推荐指数
1
解决办法
2815
查看次数

当我们有新的/删除时,为什么要使用malloc/free?

有什么用的malloc,并free当我们有newdeleteC++中.我想这两个功能freedelete是一样的.

c++ memory-management

5
推荐指数
2
解决办法
2198
查看次数

捕获内存分配异常

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的意思是什么.在这种情况下,函数如何抛出错误?要求举例说明.

谢谢你的时间和帮助.

c++ exception-handling

5
推荐指数
1
解决办法
289
查看次数

是否可以使用operator new来从堆以外的地方分配?

以下是我的应用程序的上下文:我正在使用嵌入式系统,该系统使用来自不同设备的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)

c++ embedded memory-management

5
推荐指数
1
解决办法
606
查看次数

如何使用operator new来计算动态内存分配的次数

给出以下代码:

int i;
...
ostingstream os;
os<<i;
string s=os.str();
Run Code Online (Sandbox Code Playgroud)

我想用ostringstream这种方式计算动态内存分配的次数.我怎样才能做到这一点?也许通过operator new

谢谢.

c++

3
推荐指数
1
解决办法
1816
查看次数

标准头文件&lt;new&gt;中的std::nothrow和std::new_handler有什么用

我遇到了一个小的标准头文件<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)
  1. 程序员如何使用struct nothrow_t它及其对象?nothrow该对象真的需要吗extern
  2. 什么时候new_handler用的?
  3. 为什么所有的都operator new/delete在块中声明extern C++

c++ std nothrow

3
推荐指数
1
解决办法
3450
查看次数

c ++中的new运算符

我正在阅读"Thinking in c ++"的第13章.以下内容来自本书.

MyType*fp = new MyType(1,2);

在运行时,调用malloc(sizeof(MyType))的等价物,使用(1,2)作为参数列表调用MyType的构造函数,并将结果地址作为this指针.到指针指向fp时.

我对这句大胆的句子感到困惑.这是什么意思?

c++ new-operator

3
推荐指数
1
解决办法
177
查看次数

c ++中的operator new,new_handler函数

这是运营商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会这样做?

c++ memory memory-management new-operator

3
推荐指数
1
解决办法
1111
查看次数

如果不使用堆,移动语义有用吗?

我对移动语义的直觉是对象字段的浅层复制,然后可能是对旧 r 值的一些破坏。然而,据我所知,当某些字段拥有指针/引用时,只有浅拷贝/深拷贝存在差异。如果您根本不使用堆,所以没有mallocor new,那么您可能不会有拥有指针的类/结构。因此,移动构造函数与常规复制构造函数没有任何区别。我的逻辑正确吗?

c++ move heap-memory move-semantics

3
推荐指数
1
解决办法
126
查看次数

覆盖标准库使用的内存分配方法?

是否可以覆盖 STL 分配、管理和释放内存的方式?如果可能的话,怎么做呢?有没有一种方法可以将处理原始内存的代码保留在一个类或文件中?

我想为我的整个程序执行此操作,以便我可以跟踪内存使用情况、时间和生命周期信息。当然纯粹是出于好奇!

c++ memory-management stl

2
推荐指数
1
解决办法
4384
查看次数

在类中使用new operator new

假设我有一个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++

0
推荐指数
1
解决办法
1522
查看次数