为什么不重载带有std :: string的运算符new与msvc / MD标志一起使用

时间:2019-09-20 20:24:53

标签: c++ memory stdstring

我有一些看起来像这样的代码。

#include <iostream>
#include <string>
void* operator new(std::size_t n){
    std::cout << "[Allocating " << n << "bytes] ";
    return malloc(n);
}

void operator delete(void* pointer) throw() {
    free(pointer);
}

int main(){

    for(int i = 0; i < 24; i++){
        std::cout << i << ": " << std::string(i, '=') << std::endl;
    }

}

这可以使用gcc编译器进行编译和运行,并且在使用带有/ MT或/ MTd标志的msvc编译器时也可以运行。但是,如果将标志设置为/ MDd或/ MD,则程序崩溃。它似乎陷入了新运算符内部的递归中。为什么我编译和链接到LIBCMT.lib时没有发生这种情况,正如我从Microsoft文档中得知的那样,这是/ MT和/ MD之间的区别。

1 个答案:

答案 0 :(得分:1)

您正在std::cout替换函数中使用<<的运算符new。该运算符可以轻松地自己调用new来执行一些分配,然后调用您的new替换,这将调用<<,依此类推,等等。

您应谨慎使用这些功能。如果要查看它们的调用方式,可以使用一些预分配的结构并对其进行记录(或简单地增加全局计数器)。

使用一组标志而不发生另一组标志的原因很可能是由于<<根据这些标志采用了不同的分配策略。这些对于实现来说是私有的,您不应该依赖它们。