我用googletest写了一个测试程序。该程序链接了两个库,gtestd.lib
和util.lib
,它们都是使用带有/ MDd的VS2010构建的
在util.lib
中,重写了C ++运算符new和delete。
inline void * _cdecl operator new[]( size_t cb )
{
Assert(cb <= UINT_MAX);
return MemAlloc((DWORD)cb);
}
inline void __cdecl operator delete[]( void * pv )
{
MemFree(pv);
}
现在奇怪的事情发生在gtest-filepath.cc
gtestd.lib
中
void FilePath::Normalize() {
.....
const char* src = pathname_.c_str();
char* const dest = new char[pathname_.length() + 1];
.....
delete[] dest;
}
&#34;新[]&#34;调用&#34; msvcr100d.dll!operator new []&#34;,但&#34; delete []&#34;调用&#34; mytestapp.exe!operator delete []&#34;在util.lib
中定义我希望new[]
和delete[]
都会调用VS运行时库,因为这是gtestd.lib
链接到的。但无论如何,我不明白为什么new[]
调用VS运行时库,但delete[]
调用重写的运行库。
答案 0 :(得分:4)
您的程序有未定义的行为,因为您违反了7.1.2中的规则:
内联函数应在每个 odr-used 的翻译单元中定义,并且在每种情况下都应具有完全相同的定义(3.2)。
从这些定义中删除inline
关键字。
您也没有遵循18.6.1中的指导原则,该指南说用户代码可能会替换数组::operator new[]()
,但在执行此操作时,应提供以下所有内容:
void* operator new[](std::size_t size);
void operator delete[](void* ptr) noexcept;
void operator delete[](void* ptr, std::size_t size) noexcept;
您未能提供双参数::operator delete[]
重载,在构造函数抛出时使用,并且您的替换noexcept
版本上没有正确的::operator delete[]
注释。