2013-04-15 3 views
8

Я довольно новичок в управлении памятью C++, потому что в отличие от C есть больше препятствий для освобождения всей памяти.Как действительно удалить векторы

Я пытаюсь успешно удалить указатель на вектор любого типа (т.е. вектор * данные)

/** 
* We test the program in accessing vectors 
* with dynamic storage 
**/ 
#include <iostream> 
#include <vector> // you must include this to use vectors 

using namespace std; 

int main (void){ 
    // Now let's test the program with new and delete 
    // for no memory leaks with vectors (type safe) 
    // however, just calling delete is not enough to free all memory 
    // at runtime 
    vector <int> * test_vect = new vector <int> (10,5); 

    // Print out its size 
    cout << "The size of the vector is " << test_vect->size() 
     << " elements" << endl; 

    // run through vector and display each element within boundary 
    for (long i = 0; i < (long)test_vect->size(); ++i){ 
     cout << "Element " << i << ": " << test_vect->at(i) << endl; 
    } 

    delete test_vect; 
    return EXIT_SUCCESS; 
} 

Однако я получаю утечку памяти после использования Valgrind

==2301== HEAP SUMMARY: 
==2301==  in use at exit: 4,184 bytes in 2 blocks 
==2301== total heap usage: 4 allocs, 2 frees, 4,248 bytes allocated 
==2301== 
==2301== LEAK SUMMARY: 
==2301== definitely lost: 0 bytes in 0 blocks 
==2301== indirectly lost: 0 bytes in 0 blocks 
==2301==  possibly lost: 0 bytes in 0 blocks 
==2301== still reachable: 4,096 bytes in 1 blocks 
==2301==   suppressed: 88 bytes in 1 blocks 

Как я могу быть в состоянии избавиться от всех следов утечек памяти с указателем на вектор (т. е. во время выполнения)?

+4

'вектор * test_vect = ...' бросает вызов самой цели, почему вектор существует в первую очередь. – Nawaz

+1

Почему вы используете указатели с векторами ..? – Rapptz

+1

", потому что в отличие от C, существует больше препятствий для освобождения всей памяти." Wat. – GManNickG

ответ

22

Для начала, я не верю, что есть утечка. Вы правильно прочитать Leak Summary вы вывесили в программе ?:

==2301== LEAK SUMMARY: 
==2301== definitely lost: 0 bytes in 0 blocks 
==2301== indirectly lost: 0 bytes in 0 blocks 
==2301==  possibly lost: 0 bytes in 0 blocks 
==2301== still reachable: 4,096 bytes in 1 blocks 
==2301==   suppressed: 88 bytes in 1 blocks 

Вы потеряли 0 байт в 0 блоков. valgrind не может найти определенных, косвенных или возможных утечек. Ваша программа в порядке.

Как и в стороне: Вы ... на самом деле не должен использовать new или delete в этой ситуации с этим вектором. C++, точно так же, как C, имеет вещи, которые попадают в стек и выходят за рамки, если вы объявляете их как обычные переменные. Следующий код обеспечивает именно то, что вы сделали в вашем вопросе, без использования новых и удаления:

int main (void){ 
    // Now let's test the program with new and delete 
    // for no memory leaks with vectors (type safe) 
    // however, just calling delete is not enough to free all memory 
    // at runtime (ThePhD: it is, actually!) 
    vector <int> test_vect(10,5); 

    // Print out its size 
    cout << "The size of the vector is " << test_vect.size() 
     << " elements" << endl; 

    // run through vector and display each element within boundary 
    for (long i = 0; i < (long)test_vect.size(); ++i){ 
     cout << "Element " << i << ": " << test_vect.at(i) << endl; 
    } 

    // (ThePhD: Look ma, no deletions!) 
    return EXIT_SUCCESS; 
} 

стек очиститься волшебно, потому что станд :: вектор имеет деструктор, который чистит свои ресурсы, когда это выходит за рамки. Вам не нужно делать его динамичным и помещать его в область памяти кучи/свободного хранилища программной памяти, когда стек будет делать это просто отлично.

Кроме того, похоже, что вы пришли из C, поэтому я буду тратить время, чтобы сказать: Добро пожаловать на C++. : D

+2

<3 @ Rapptz за то, что дал мне знать, как на самом деле читать Вальгринд. : D –

+1

Хотя ваше предложение работает для небольших и простых программ, что бы я сделал, если мне действительно нужно сделать динамически выделенную память для вектора? Вектор, который длится выше вызова функции. – JBRPG

+0

@JBRPG Вы передаете свой вектор как возвращаемое значение (это быстро, потому что у C++ теперь есть 'std :: move' и друзья), или вы динамически выделяете вектор и отслеживаете его самостоятельно. Вы также можете сделать 'std :: unique_ptr >', и это будет иметь ту же семантику, что и указатель на std :: vector, но с автоматическим удалением после того, как вы передали новый вектор. Вы также можете передавать вещи по ссылке в функциях C++, работать с ними, а значение после существования функции будет напрямую изменено. Отличное время для C++. : D –

6

Я думаю, что это может быть ответ. Что касается C++, здесь нет утечки.

3

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

Динамическое создание контейнера само по себе поражает цель и почти всегда совершенно бессмысленно.

И да, в вашем случае вектор действительно удален.

+0

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

+2

Его не просто вектор, есть многочисленные классы контейнеров в стандартной библиотеке C++ и даже больше в таких библиотеках, как Qt или boost. – dtech

-3

Я думаю, вам нужно позвонить

if(test_vect != 0) 
{ 
    if(!test_vect->empty()) 
     test_vect->clear(); 
} 

перед удалением его

+3

№ Это не имеет к этому никакого отношения. –

 Смежные вопросы

  • Нет связанных вопросов^_^