векторный указатель, вызывающий утечку памяти valgrind - PullRequest
1 голос
/ 17 февраля 2012

Я пытаюсь выучить C ++ и valgrind. Поэтому я написал следующий код, чтобы проверить это. Но я получаю некоторые утечки памяти. Кто-нибудь может объяснить, что вызывает утечку памяти? Заранее спасибо.

#include <vector>
#include <iostream>
using namespace std;

class test
{
     int c;
      public:
      void whatever();
}; 
void test:: whatever()
{
     vector<test*> a;
     if(true)
     {
           test* b = new test();
           b->c = 1;
           a.push_back(b);
     }
     test* d = a.back();
     cout << "prints: " << d->c;
     delete d;
}

int main()
{
    test* a = new test();
    a->whatever();
    return 1;
}

из Вальгринда

==28548== HEAP SUMMARY:
==28548==     in use at exit: 4 bytes in 1 blocks
==28548==   total heap usage: 3 allocs, 2 frees, 16 bytes allocated
==28548==
==28548== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==28548==    at 0x4C27CC1: operator new(unsigned long) (vg_replace_malloc.c:261)
==28548==    by 0x400C36: main (in a.out)
==28548==
==28548== LEAK SUMMARY:
==28548==    definitely lost: 4 bytes in 1 blocks
==28548==    indirectly lost: 0 bytes in 0 blocks
==28548==      possibly lost: 0 bytes in 0 blocks
==28548==    still reachable: 0 bytes in 0 blocks
==28548==         suppressed: 0 bytes in 0 blocks
==28548==
==28548== For counts of detected and suppressed errors, rerun with: -v
==28548== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)

Мне не разрешено удалять из копии указатель или я делаю что-то еще неправильно?

Ответы [ 3 ]

2 голосов
/ 17 февраля 2012

Вы никогда не звоните delete на a.

Конечно, важным моментом здесь является то, что вы используете vector указателей.С какой стати ты это сделал?Пусть вектор позаботится об управлении памятью за вас!

1 голос
/ 17 февраля 2012

Вы забыли delete a; в конце main().

Обратите внимание, что все, что вы написали, не должно никогда переходить в реальный код.Вы никогда не должны использовать динамическое распределение (new), если вам абсолютно не нужно и точно знать, почему.


Если вы хотите сохранить вектор указателей в образовательных целях, то вот лучший способ написанияэто:

#include <vector>
#include <memory>  // for unique_ptr

// intentionally left blank; NO abusing namespace std!

struct Foo
{
    int c;

    void whatever()
    {
        std::vector<std::unique_ptr<test>> v;

        if (true)
        {
            v.emplace_back(new test);
            v.back()->c = 1;
        }

        // everything is cleaned up automagically
    }
};

int main()
{
    Test a;        // automatic, not dynamic
    a.whatever();

    return 1;
}

Это все еще только для образовательных целей;в реальной жизни вы бы очень старались обойтись с простой std::vector<test>, поскольку vector уже уже является динамической структурой данных и нет необходимости в дополнительном уровне косвенности.

0 голосов
/ 17 февраля 2012

Утечка памяти в основном. Вы не удаляете выделенный объект test.

...