2016-07-11 3 views
0

Я некоторое время был вокруг сообщества C++, чтобы услышать, что необработанные указатели «злы» и что их следует избегать как можно больше. Хотя одной из основных причин использования интеллектуальных указателей над исходными указателями является «предотвращение» утечек памяти. Поэтому мой вопрос: даже если вы используете интеллектуальные указатели, возможно ли утечка памяти? Если да, то как это будет возможно?Возможные утечки памяти с помощью интеллектуальных указателей

+1

Может найти [** этот вопрос **] (http://stackoverflow.com/questions/1826902/how-to -avoid-memory-leak-with-shared-ptr) интересно. Вероятно, [** this one **] (http://stackoverflow.com/questions/67174/find-memory-leaks-caused-by-smart-pointers) тоже. Оба они напрямую связаны с вашим преобладающим вопросом (и были найдены путем поиска «при использовании интеллектуальных указателей, возможно ли утечка памяти» на этом сайте). – WhozCraig

ответ

5

Даже при использовании интеллектуальных указателей, возможно ли иметь память ?

Да, если вы не будете стараться избегать создания цикла в своих ссылках.

Если да, то как это будет возможно?

Смарт-указатели, основанные на подсчете ссылок (например, shared_ptr), удалят направленный объект, когда счетчик ссылок, связанный с объектом, падает до нуля. Но если у вас есть цикл в ваших ссылках (A-> B-> A или какой-то более сложный цикл), то подсчет ссылок в цикле никогда не упадет до нуля, потому что умные указатели «поддерживают друг друга живыми».

Ниже приведен пример простой программы, которая утечки памяти, несмотря на использование только shared_ptr для указателей. Обратите внимание, что при запуске, конструкторам напечатать сообщение, но деструкторы никогда не делать:

#include <stdio.h> 
#include <memory> 

using namespace std; 

class C 
{ 
public: 
    C() {printf("Constructor for C: this=%p\n", this);} 
    ~C() {printf("Destructor for C: this=%p\n", this);} 

    void setSharedPointer(shared_ptr<C> p) {pC = p;} 

private: 
    shared_ptr<C> pC; 
}; 

int main(int argc, char ** argv) 
{ 
    shared_ptr<C> pC(new C); 
    shared_ptr<C> pD(new C); 

    pC->setSharedPointer(pD); 
    pD->setSharedPointer(pC); 

    return 0; 
} 
+1

Непонятно, что вы подразумеваете под «самыми» умными указателями. В стандарте C++ есть два (и слабый ptr, который не является умным указателем на свой собственный, но местозаполнитель для получения интеллектуального указателя), и один из них использует счетчик ссылок, а другой - нет. – SergeyA

+0

Я исправил это, спасибо. –

-1

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

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