MySQL C ++ Коннектор утечки памяти - PullRequest
0 голосов
/ 19 апреля 2020

Я действительно просматривал похожие посты, но не смог найти ничего подходящего для моей проблемы.

Я пытаюсь создать базовую c программу, которая выполняет запросы с MySQL база данных, и все это прекрасно работает, но у меня много утечек памяти.

#include <cppconn/driver.h>

#include <crtdbg.h>

int main() {

    {
        sql::Driver* driver = get_driver_instance();
    }

    _CrtDumpMemoryLeaks();
    return 0;
}

Это небольшой фрагмент того, что я использую. В остальном это не очень актуально, так как я заметил, что даже этот небольшой кусочек кода приводит к большим утечкам памяти, как указано в вызове _CrtDumpMemoryLeaks.

Я получил 64-битную версию и использовал динамически связанная библиотека. Я заметил, что мне также нужно было отдельно связать библиотеку надстройки, поэтому я скачал ее и также поместил в нее каталог «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.

Так что, похоже, многое просачивается, только при вызове этого единственного метода в классе Driver. Деструктор защищен, поэтому я не могу вызвать «удалить» на нем.

1 Ответ

1 голос
/ 19 апреля 2020

Это на самом деле не утечка памяти, потому что вы проверяете «слишком рано».

Здесь вы можете увидеть, как реализовано 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 s с невидимыми MySQL_Driver объектами. get_driver_instance просто вызывает get_driver_instance_by_name(""), который возвращает драйвер driver[""] или создает его, если он не существует.

В документации shared_ptr вы можете видеть, что shared_ptr будет delete указатель, который был назначен ему, когда сам shared_ptr уничтожен. Он будет разрушен, когда карта driver будет разрушена, что произойдет, если ваш процесс будет сорван - после того, как main вернется.

Итак, в main драйвер все еще существует (деструкторы еще не запущены), поэтому _CrtDumpMemoryLeaks(); сообщит об этом как о фиктивной утечке.

Это в основном проблема, описанная здесь .

I ' Я не уверен, существует ли надежный способ запуска вашего кода после деструкторов, потому что порядок, в котором выполняются глобальные деструкторы и обработчики atexit, не указывается в разных единицах перевода.

Поскольку вы находитесь на Windows, одна идея состояла бы в том, чтобы (ab) использовать обратные вызовы локального хранилища потока, вы могли бы запустить код на шаге DLL_THREAD_DETACH, который, насколько я знаю, должен запускать после обычных деструкторов и тому подобное , См. эту статью . (Хотя я не уверен в этом, поэтому я был бы рад, если бы кто-то мог прокомментировать, кто знает это лучше, чем я!)

...