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

Why doesn't overloading operator new with std::string work with msvc /MD flag

本文关键字:msvc 标志 MD 一起 string 运算符 重载 std 为什么      更新时间:2023-10-16

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

#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 之间的区别。

您在new替换函数中使用std::cout运算符<<。此运算符可以轻松地调用new本身来执行一些分配,进而调用您的new替换,这将调用<<,依此类推。

您应该小心您在这些函数中执行的操作。如果你想看看它们是如何被调用的,你可以使用一些预分配的结构并使用它们进行记录(或者简单地增加一个全局计数器(。

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