有一种解决方案,其中动态库(SharedLibrary)提供接口(抽象类),另一个项目提供其实现(派生类)。最小示例概念:
该类Website
为放置 URL 的缓冲区分配 64 KB。此外,在不离开构造函数的情况下,模拟异常。预期会Website
调用析构函数,但仅调用基类析构函数InternetResource
:
Website::ctor
InternetResource::dtor
main::catch 'Oops!'
因此,分配的内存没有被释放:
解决方案
来源
//
// Application/Main.cpp
//
#include <iostream>
#include "Website.hpp"
int main()
{
try
{
__debugbreak(); // for heap snapshot (1)
Website site("https://stackoverflow.com"); // throws
return 1; // unattainable
}
catch (const std::exception& e)
{
std::cout
<< "main::catch '"
<< e.what()
<< "'"
<< std::endl;
}
__debugbreak(); // for heap snapshot (2)
return 0;
}
//
// Application/Website.hpp
//
#pragma once
#include <SharedLibrary/InternetResource.hpp>
class Website : public InternetResource
{
public:
Website(const char* url);
virtual ~Website();
void* Buffer = nullptr;
};
//
// Application/Website.cpp
//
#include "Website.hpp"
#include <iostream>
#include <memory>
Website::Website(const char* url)
{
std::cout << "Website::ctor" << std::endl;
this->Buffer = malloc(1 << 16); // 64 kB
memcpy_s(this->Buffer, 1 << 16, url, strlen(url));
throw std::exception("Oops!");
}
Website::~Website()
{
std::cout << "Website::dtor" << std::endl;
free(this->Buffer);
this->Buffer = nullptr;
}
//
// SharedLibrary/Dll.hpp
//
#pragma once
#ifdef SHARED_LIBRARY_EXPORTS
# define SHARED_LIBRARY_API __declspec(dllexport)
#else
# define SHARED_LIBRARY_API __declspec(dllimport)
#endif
//
// SharedLibrary/InternetResource.hpp
//
#pragma once
#include "Dll.hpp"
class SHARED_LIBRARY_API InternetResource
{
public:
virtual ~InternetResource();
};
//
// SharedLibrary/InternetResource.cpp
//
#include "InternetResource.hpp"
#include <iostream>
InternetResource::~InternetResource()
{
std::cout << "InternetResource::dtor" << std::endl;
}
--
-- Premake5.lua
--
workspace "WhatTheDtor"
location("Build/")
configurations { "Debug" }
platforms { "x86" }
function cpp_commons()
language "C++"
cppdialect "C++17"
defines { "DEBUG" }
symbols "On"
runtime "Debug"
staticruntime "Off" -- /MDd
exceptionhandling ("Default") -- /EHsc
end
project "SharedLibrary"
kind "SharedLib"
cpp_commons()
files { "./SharedLibrary/**.cpp", "./SharedLibrary/**.hpp" }
defines { "SHARED_LIBRARY_EXPORTS" }
project "Application"
kind "ConsoleApp"
cpp_commons()
files { "./Application/**.cpp", "./Application/**.hpp" }
includedirs { "." }
dependson { "SharedLibrary" }
links { "SharedLibrary" }
回放
Application
通过和收集文件SharedLibrary
。- 使用 premake5 创建解决方案文件。
premake5 vs2022
- 打开“./Build/WhatTheDtor.sln”。
- 使用堆分析构建并开始调试。
- 在嵌入断点处拍摄堆的两个快照。
就这样。在这里您可以看到 64 KB 的未释放内存。