c++ - 为什么不调用覆盖的 `operator new`?

标签 c++ visual-studio-2005 operator-overloading new-operator

我在 VS2005 中运行以下代码:

#include <iostream>
#include <string>
#include <new>
#include <stdlib.h>

int flag = 0;

void* my_alloc(std::size_t size)
{
    flag = 1;
    return malloc(size);
}

void* operator new(std::size_t size) { return my_alloc(size); }
void operator delete(void* ptr) { free(ptr); }
void* operator new[](std::size_t size) { return my_alloc(size); }
void operator delete[](void* ptr) { free(ptr); }

int main()
{
    std::string str;
    std::getline(std::cin, str);
    std::cout << str;
    return flag;
}

我输入了一个足够长的字符串(比小字符串优化缓冲区长):

0123456789012345678901234567890123456789012345678901234567890123456789

在 Debug 编译过程返回 1,在 Release 配置过程返回 0,这意味着 new 运算符没有被调用!我可以通过放置断点、写入输出/调试输出等来验证这一点...

这是为什么,这是一种符合标准的行为吗?

最佳答案

经过一些研究,@bart-jan 在他们的其他答案(现已删除)中所写的内容实际上是正确的。

可以很容易地看出,我的运算符(operator)根本没有在 Release 中调用,而是调用了 CRT 版本。 (不,对于所有在黑暗中拍摄的人来说,这里没有递归。)问题是“为什么”?

以上是针对动态链接的 CRT(默认)编译的。 Microsoft 在 CRT DLL 中提供了 std::string 的实例化(以及许多其他标准模板)。查看 VS2005 附带的 Dinkumware header :

#if defined(_DLL_CPPLIB) && !defined(_M_CEE_PURE)

template class _CRTIMP2_PURE allocator<char>;
// ...
template class _CRTIMP2_PURE basic_string<char, char_traits<char>,
    allocator<char> >;

其中 _CRTIMP2_PURE 扩展为 __declspec(dllimport)。这意味着在 Release 中,链接器将 std::string 链接到构建 CRT 时实例化的版本,它使用 new 的默认实现。

不清楚为什么它不会在调试中发生。正如@Violet Giraffe 猜对的那样,它一定受到某些开关的影响。但是,我认为这是链接器开关,而不是编译器开关。我无法确定哪个开关很重要。

其他答案忽略的剩余问题是“它是标准的”吗?在 VS2010 中尝试代码,无论我编译什么配置,它确实调用了我的 operator new !查看 VS2010 附带的 header ,它表明 Dinkumware 删除了上述实例化的 __declspec(dllimport)。因此,我相信旧行为确实是一个编译器错误,不是标准。

关于c++ - 为什么不调用覆盖的 `operator new`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8257236/

相关文章:

c++ - 在这种情况下是 clang 错误、gcc 错误还是两者都错误 - 用成员指针抛弃 constness

c# - 调整 GridView 编辑文本框大小

c++ - 在 c++ vs140 (Visual Studio 2015) 下编译的 Visual Studio 项目中使用在 vs80 (Visual Studio 2005) 下编译 C++ 的静态库

C++ 使用 operator int() 而不是 operator+

C++:如何为字符数组创建比较函数?

c++ - 为类对象赋值

c++ - 为套接字轮询/选择设置超时值的最佳做法是什么?

c++ - 递归函数引起的栈溢出

ASP.NET 成员(member) : Login Controls Source Code

c++ - 重载 operator<< 时 std::endl 的类型未知