MySQL C++ 连接器内存泄漏
MySQL C++ Connector memory leaks
我真的一直在浏览类似的帖子,但找不到适合我的问题的帖子。
我正在尝试制作一个使用 MySQL 数据库进行查询的基本程序,一切正常,但我有很多内存泄漏。
#include <cppconn/driver.h>
#include <crtdbg.h>
int main() {
{
sql::Driver* driver = get_driver_instance();
}
_CrtDumpMemoryLeaks();
return 0;
}
这是我正在使用的一小段代码。其余部分并不真正相关,因为我观察到即使是这一小段代码也会产生大量内存泄漏,如 _CrtDumpMemoryLeaks 调用所示。
我得到了 64 位版本并使用了动态 linked 库。我观察到我还需要单独 link boost 库,所以我下载了它并将其也放在 "include" 目录中。
我正在使用 Visual Studio 2019 社区。
如有任何帮助,我们将不胜感激。干杯!
这是 运行 程序后的输出。
Detected memory leaks!
Dumping objects ->
{193} normal block at 0x0000014FB1F74710, 16 bytes long.
Data: < F O > 90 46 FA B1 4F 01 00 00 00 00 00 00 00 00 00 00
{192} normal block at 0x0000014FB1FA4670, 88 bytes long.
Data: < ( O ( O > 00 28 F6 B1 4F 01 00 00 00 28 F6 B1 4F 01 00 00
{191} normal block at 0x0000014FB1F8CC30, 24 bytes long.
Data: < g > 18 03 67 C5 FE 7F 00 00 01 00 00 00 01 00 00 00
{190} normal block at 0x0000014FB1F8C7B0, 24 bytes long.
Data: < d > A8 96 64 C5 FE 7F 00 00 02 00 00 00 01 00 00 00
{189} normal block at 0x0000014FB1F5E280, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{188} normal block at 0x0000014FB1F57FE0, 168 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 88 00 00 00 00 00 00 00
{187} normal block at 0x0000014FB1F5F5A0, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{186} normal block at 0x0000014FB1F61720, 56 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 18 00 00 00 00 00 00 00
{185} normal block at 0x0000014FB1F71050, 48 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 10 00 00 00 00 00 00 00
{184} normal block at 0x0000014FB1F70DB0, 40 bytes long.
Data: < p O > 00 00 00 00 CD CD CD CD 70 10 F7 B1 4F 01 00 00
{183} normal block at 0x0000014FB1F70D40, 48 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 10 00 00 00 00 00 00 00
{182} normal block at 0x0000014FB1F710C0, 40 bytes long.
Data: < ` O > 00 00 00 00 CD CD CD CD 60 0D F7 B1 4F 01 00 00
{181} normal block at 0x0000014FB1F64C10, 80 bytes long.
Data: <h i dRi > 68 C6 69 C5 FE 7F 00 00 64 52 69 C5 FE 7F 00 00
{180} normal block at 0x0000014FB1F743F0, 16 bytes long.
Data: < L O > 01 00 00 00 00 00 00 00 10 4C F6 B1 4F 01 00 00
{179} normal block at 0x0000014FB1F5BF60, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{178} normal block at 0x0000014FB1F57280, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{177} normal block at 0x0000014FB1F55310, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{176} normal block at 0x0000014FB1F55560, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{175} normal block at 0x0000014FB1F5E560, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{174} normal block at 0x0000014FB1F55EE0, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{173} normal block at 0x0000014FB1F57530, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{172} normal block at 0x0000014FB1F57C50, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{171} normal block at 0x0000014FB1F57960, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{170} normal block at 0x0000014FB1F744E0, 8 bytes long.
Data: <8 d > 38 94 64 C5 FE 7F 00 00
{169} normal block at 0x0000014FB1F62560, 24 bytes long.
Data: <0 d D O > 30 8C 64 C5 FE 7F 00 00 E0 44 F7 B1 4F 01 00 00
{168} normal block at 0x0000014FB1F743A0, 16 bytes long.
Data: < f `% O > F0 FE 66 C5 FE 7F 00 00 60 25 F6 B1 4F 01 00 00
{167} normal block at 0x0000014FB1F62800, 88 bytes long.
Data: <pF O pF O > 70 46 FA B1 4F 01 00 00 70 46 FA B1 4F 01 00 00
{166} normal block at 0x0000014FB1F74850, 16 bytes long.
Data: < s > 98 73 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{162} normal block at 0x0000014FB1F65510, 80 bytes long.
Data: < U O U O > 10 55 F6 B1 4F 01 00 00 10 55 F6 B1 4F 01 00 00
{161} normal block at 0x0000014FB1F74F30, 16 bytes long.
Data: < > D8 D4 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{160} normal block at 0x0000014FB1F73080, 120 bytes long.
Data: < 0 O 0 O > 80 30 F7 B1 4F 01 00 00 80 30 F7 B1 4F 01 00 00
{159} normal block at 0x0000014FB1F74D00, 16 bytes long.
Data: < > F0 D4 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{158} normal block at 0x0000014FB1F750C0, 16 bytes long.
Data: <hs > 68 73 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{157} normal block at 0x0000014FB1F72FE0, 88 bytes long.
Data: < / O / O > E0 2F F7 B1 4F 01 00 00 E0 2F F7 B1 4F 01 00 00
{156} normal block at 0x0000014FB1F74350, 16 bytes long.
Data: < X > 00 58 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
Object dump complete.
所以看起来很多东西都在泄漏,只是通过调用驱动程序上的那个方法 class。析构函数受到保护,所以我无法对其调用 "delete"。
这不是真正的内存泄漏,因为您正在检查 "too early"。
Here可以看到get_driver_instance
是如何实现的:
static std::map< sql::SQLString, boost::shared_ptr<MySQL_Driver> > driver;
CPPCONN_PUBLIC_FUNC sql::mysql::MySQL_Driver * get_driver_instance()
{
return get_driver_instance_by_name("");
}
CPPCONN_PUBLIC_FUNC sql::mysql::MySQL_Driver * get_driver_instance_by_name(const char * const clientlib)
{
::sql::SQLString dummy(clientlib);
std::map< sql::SQLString, boost::shared_ptr< MySQL_Driver > >::const_iterator cit;
if ((cit = driver.find(dummy)) != driver.end()) {
return cit->second.get();
} else {
boost::shared_ptr< MySQL_Driver > newDriver;
newDriver.reset(new MySQL_Driver(dummy));
driver[dummy] = newDriver;
return newDriver.get();
}
}
你可以看到创建了一个全局变量driver
,它是shared_ptr
到单个MySQL_Driver
对象的映射。 get_driver_instance
简单地调用 get_driver_instance_by_name("")
它将 return 驱动程序 driver[""]
或者如果它不存在则创建它。
在 shared_ptr
documentation 中你可以看到当 shared_ptr
本身被破坏时,shared_ptr
将 delete
分配给它的指针。它会在映射 driver
被破坏时被破坏,这将在您的进程被拆除时发生 - after main
returns.
因此,在 main
内,驱动程序仍然存在(析构函数还没有 运行),因此 _CrtDumpMemoryLeaks();
会将其报告为虚假泄漏。
这基本上就是描述的问题 here。
我不确定在析构函数之后是否有可靠的方法 运行 你的代码,因为全局析构函数和 atexit
处理程序 运行 的顺序不是在不同的翻译单元中指定。
由于您在 Windows,一个想法是(滥用)使用线程本地存储回调,您可以 运行 在 DLL_THREAD_DETACH
步骤编写代码,据我所知,运行 在 常规析构函数等之后。参见 this article。 (虽然我不确定,所以如果有人能发表比我更了解这一点的评论,我会很高兴!)
我真的一直在浏览类似的帖子,但找不到适合我的问题的帖子。
我正在尝试制作一个使用 MySQL 数据库进行查询的基本程序,一切正常,但我有很多内存泄漏。
#include <cppconn/driver.h>
#include <crtdbg.h>
int main() {
{
sql::Driver* driver = get_driver_instance();
}
_CrtDumpMemoryLeaks();
return 0;
}
这是我正在使用的一小段代码。其余部分并不真正相关,因为我观察到即使是这一小段代码也会产生大量内存泄漏,如 _CrtDumpMemoryLeaks 调用所示。
我得到了 64 位版本并使用了动态 linked 库。我观察到我还需要单独 link boost 库,所以我下载了它并将其也放在 "include" 目录中。
我正在使用 Visual Studio 2019 社区。
如有任何帮助,我们将不胜感激。干杯!
这是 运行 程序后的输出。
Detected memory leaks!
Dumping objects ->
{193} normal block at 0x0000014FB1F74710, 16 bytes long.
Data: < F O > 90 46 FA B1 4F 01 00 00 00 00 00 00 00 00 00 00
{192} normal block at 0x0000014FB1FA4670, 88 bytes long.
Data: < ( O ( O > 00 28 F6 B1 4F 01 00 00 00 28 F6 B1 4F 01 00 00
{191} normal block at 0x0000014FB1F8CC30, 24 bytes long.
Data: < g > 18 03 67 C5 FE 7F 00 00 01 00 00 00 01 00 00 00
{190} normal block at 0x0000014FB1F8C7B0, 24 bytes long.
Data: < d > A8 96 64 C5 FE 7F 00 00 02 00 00 00 01 00 00 00
{189} normal block at 0x0000014FB1F5E280, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{188} normal block at 0x0000014FB1F57FE0, 168 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 88 00 00 00 00 00 00 00
{187} normal block at 0x0000014FB1F5F5A0, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{186} normal block at 0x0000014FB1F61720, 56 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 18 00 00 00 00 00 00 00
{185} normal block at 0x0000014FB1F71050, 48 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 10 00 00 00 00 00 00 00
{184} normal block at 0x0000014FB1F70DB0, 40 bytes long.
Data: < p O > 00 00 00 00 CD CD CD CD 70 10 F7 B1 4F 01 00 00
{183} normal block at 0x0000014FB1F70D40, 48 bytes long.
Data: < > 00 00 00 00 D2 04 00 00 10 00 00 00 00 00 00 00
{182} normal block at 0x0000014FB1F710C0, 40 bytes long.
Data: < ` O > 00 00 00 00 CD CD CD CD 60 0D F7 B1 4F 01 00 00
{181} normal block at 0x0000014FB1F64C10, 80 bytes long.
Data: <h i dRi > 68 C6 69 C5 FE 7F 00 00 64 52 69 C5 FE 7F 00 00
{180} normal block at 0x0000014FB1F743F0, 16 bytes long.
Data: < L O > 01 00 00 00 00 00 00 00 10 4C F6 B1 4F 01 00 00
{179} normal block at 0x0000014FB1F5BF60, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{178} normal block at 0x0000014FB1F57280, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{177} normal block at 0x0000014FB1F55310, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{176} normal block at 0x0000014FB1F55560, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{175} normal block at 0x0000014FB1F5E560, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{174} normal block at 0x0000014FB1F55EE0, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{173} normal block at 0x0000014FB1F57530, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{172} normal block at 0x0000014FB1F57C50, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{171} normal block at 0x0000014FB1F57960, 104 bytes long.
Data: < > FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00
{170} normal block at 0x0000014FB1F744E0, 8 bytes long.
Data: <8 d > 38 94 64 C5 FE 7F 00 00
{169} normal block at 0x0000014FB1F62560, 24 bytes long.
Data: <0 d D O > 30 8C 64 C5 FE 7F 00 00 E0 44 F7 B1 4F 01 00 00
{168} normal block at 0x0000014FB1F743A0, 16 bytes long.
Data: < f `% O > F0 FE 66 C5 FE 7F 00 00 60 25 F6 B1 4F 01 00 00
{167} normal block at 0x0000014FB1F62800, 88 bytes long.
Data: <pF O pF O > 70 46 FA B1 4F 01 00 00 70 46 FA B1 4F 01 00 00
{166} normal block at 0x0000014FB1F74850, 16 bytes long.
Data: < s > 98 73 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{162} normal block at 0x0000014FB1F65510, 80 bytes long.
Data: < U O U O > 10 55 F6 B1 4F 01 00 00 10 55 F6 B1 4F 01 00 00
{161} normal block at 0x0000014FB1F74F30, 16 bytes long.
Data: < > D8 D4 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{160} normal block at 0x0000014FB1F73080, 120 bytes long.
Data: < 0 O 0 O > 80 30 F7 B1 4F 01 00 00 80 30 F7 B1 4F 01 00 00
{159} normal block at 0x0000014FB1F74D00, 16 bytes long.
Data: < > F0 D4 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{158} normal block at 0x0000014FB1F750C0, 16 bytes long.
Data: <hs > 68 73 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
{157} normal block at 0x0000014FB1F72FE0, 88 bytes long.
Data: < / O / O > E0 2F F7 B1 4F 01 00 00 E0 2F F7 B1 4F 01 00 00
{156} normal block at 0x0000014FB1F74350, 16 bytes long.
Data: < X > 00 58 E1 C5 FE 7F 00 00 00 00 00 00 00 00 00 00
Object dump complete.
所以看起来很多东西都在泄漏,只是通过调用驱动程序上的那个方法 class。析构函数受到保护,所以我无法对其调用 "delete"。
这不是真正的内存泄漏,因为您正在检查 "too early"。
Here可以看到get_driver_instance
是如何实现的:
static std::map< sql::SQLString, boost::shared_ptr<MySQL_Driver> > driver;
CPPCONN_PUBLIC_FUNC sql::mysql::MySQL_Driver * get_driver_instance()
{
return get_driver_instance_by_name("");
}
CPPCONN_PUBLIC_FUNC sql::mysql::MySQL_Driver * get_driver_instance_by_name(const char * const clientlib)
{
::sql::SQLString dummy(clientlib);
std::map< sql::SQLString, boost::shared_ptr< MySQL_Driver > >::const_iterator cit;
if ((cit = driver.find(dummy)) != driver.end()) {
return cit->second.get();
} else {
boost::shared_ptr< MySQL_Driver > newDriver;
newDriver.reset(new MySQL_Driver(dummy));
driver[dummy] = newDriver;
return newDriver.get();
}
}
你可以看到创建了一个全局变量driver
,它是shared_ptr
到单个MySQL_Driver
对象的映射。 get_driver_instance
简单地调用 get_driver_instance_by_name("")
它将 return 驱动程序 driver[""]
或者如果它不存在则创建它。
在 shared_ptr
documentation 中你可以看到当 shared_ptr
本身被破坏时,shared_ptr
将 delete
分配给它的指针。它会在映射 driver
被破坏时被破坏,这将在您的进程被拆除时发生 - after main
returns.
因此,在 main
内,驱动程序仍然存在(析构函数还没有 运行),因此 _CrtDumpMemoryLeaks();
会将其报告为虚假泄漏。
这基本上就是描述的问题 here。
我不确定在析构函数之后是否有可靠的方法 运行 你的代码,因为全局析构函数和 atexit
处理程序 运行 的顺序不是在不同的翻译单元中指定。
由于您在 Windows,一个想法是(滥用)使用线程本地存储回调,您可以 运行 在 DLL_THREAD_DETACH
步骤编写代码,据我所知,运行 在 常规析构函数等之后。参见 this article。 (虽然我不确定,所以如果有人能发表比我更了解这一点的评论,我会很高兴!)