表題通りのめんどくさいエラーに遭遇したのでメモ書きです。
開発環境はMSVCのMicrosoft Visual Studio Community 2022 (64 ビット) - Current Version 17.3.5です。
以下のように、仮想継承したクラスのunique_ptrをキャストして返すと、ヒープエラーを起こして死ぬことができます。
#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #include <memory> using namespace std; class Base{}; class Extends : public virtual Base{}; unique_ptr<Base> CreatePointer() { auto a = make_unique<Extends>(); return a; } int main() { { auto d = CreatePointer(); } _CrtDumpMemoryLeaks(); return 0; }
HEAP[ConsoleApplication1.exe]: Invalid address specified to RtlValidateHeap( 0000014A9EA50000, 0000014A9EA61648 ) ブレークポイント命令 (__debugbreak() ステートメントまたは類似の呼び出し) が ConsoleApplication1.exe で実行されました。 Debug Assertion Failed! Program: ...demCpp\windows\TBSKmodemCpp\x64\Debug\ConsoleApplication1.exe File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp Line: 904 Expression: _CrtIsValidHeapPointer(block) For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts.
回避方法
shared_ptrにすると正常に動作します。
shared_ptr<Base> CreatePointer() { auto a = make_shared<Extends>(); return a; }
virtualを取り除いても正常に動作します。
class Extends : public Base{};
MSVC固有の問題なのかの切り分けまではしていません。