2017-06-14 117 views
-1

我已經定義了一個指針列表。在清除清單之前,我應該如何釋放所有這些指針?清除所有列表成員的最佳方法是什麼?在下面的程序中,是否需要釋放爲struct分配的內存?看到我的內嵌評論。清除C++中的STL指針列表

struct MyStruct { 
    char *data; 
    int len; 
}; 

typedef std::list<struct MyStruct *> myStruct_list; 
myStruct_list l_list; 

/* Prepare a list */ 

for(int i = 0; i < 10; i++) { 
    struct MyStruct *s = (MyStruct *)malloc(sizeof(struct MyStruct)); 
    s->data = (char*)malloc(MAX_LEN); 
    get_random_data(s->data,size); 
    s->len = strlen(s->data); 
    l_list.push_back(s); 
} 


/* Delete all members from a list */ 

myStruct_list::iterator it; 
for (it = l_list.begin(); it != l_list.end(); ++it) { 
    if (*it) { 
     free(*it);  // --->> do I need to free (*it)->data ????? 
    } 
} 
l_list.clear(); 
+4

爲什麼你甚至使用指針在這裏?我認爲沒有理由這樣做,如果你刪除它們,那麼你不必擔心泄漏:) – NathanOliver

+4

你爲什麼使用malloc?這段代碼的一半看起來更像c而不是C++。 –

+3

'std :: list :: iterator它;'我很抱歉,你是從過去?但是,嚴重的是,如果你不在這裏使用一些遺留系統,你確實需要更新你的學習資料。 – George

回答

3

我想了解是否有以下程序的任何內存泄漏?

是你,就在這裏:

p = (char*)malloc(MAX_LEN); 
p = (char *)buf; 

你分配內存並將其分配給p和下一行你失去它。所以:

  1. 你不應該,除非你需要傳遞將由C代碼來管理數據使用C++程序malloc()
  2. 你應該用特殊的數據結構像std::string等來管理您的數據。
  3. 如果您仍然需要分配動態內存使用智能指針。

我該如何調試是否有任何內存泄漏?

你不會在第一時間創建它們。例如,你怎麼能寫get_random_str(假設你真的有使用malloc分配吧):

using spchar = std::unique_ptr<char[], decltype(std::free) *>; 

spchar get_random_str(int len) 
{ 
    spchar s(static_cast<char *>(malloc(len + 1)), std::free); 
    static const char alphanum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 
    for (int i = 0; i < len; ++i) { 
     s[i] = alphanum[rand() % (sizeof(alphanum) - 1)]; 
    } 

    s[len] = '\0'; 
    return s; 
} 

注意,我沒有編譯此代碼,這是給你看的想法。

更新:看起來你認爲這個代碼:

p = (char *)buf; 

將從buf複製串p,這是情況並非如此。相反,你讓p點的buf內存鬆動舊值malloc()之前(因此創建內存泄漏),你的buf是ADRESS分配給data當你調用它free()導致UB回來,所以你需要什麼,而不是:

strncpy(p, buf, MAX_LEN); 

但即使你這樣做是沒有必要的並不是真正需要buf可言:

void myClass::fillData(void) 
{ 
    s = (MyStruct *)malloc(sizeof(struct MyStruct)); 
    s->data = (char*)malloc(MAX_LEN); 
    get_random_str(s->data,950); 
    s->len = strlen(s->data); 
    l_list.push_back(s); 
} 

但這更多的C代碼,使用一些C++的語法。如果你真的想學習C++,你應該得到更新的編譯器和教科書。使用lambda函數

+0

你說得對。它將來可能會被一些C代碼使用。這就是我使用malloc的原因。 –

+1

您仍然可以使用智能指針和自定義刪除器從malloc釋放內存。但是更大的問題是您正在編寫C代碼,而不是C++ – Slava

+1

@ M.Rock如果您正在編寫代碼以便C將來可以使用它,那麼您正在編寫C代碼。如果你的代碼是* not * C,那麼當你需要移植它時,使用'malloc'是你最擔心的問題。 –

-2

刪除元素在for_each

std::for_each(l_list.begin(), l_list.end(), [](const MyStruct* elem){if(elem) free(elem)}); 

和明確的指向:

l_list.clear(); 
+1

更好的建議是使用'std :: unique_ptr'的'std :: list',這可以保證在列表銷燬時銷燬指向的結構。當然,假設OP真的需要存儲指向結構的指針...... –

+2

imho答案「爲什麼我有內存泄漏?」應該是「因爲你正在使用原始指針」。釋放他們與症狀不是原因;) – user463035818

+4

不是dv,但'if(elem)'是多餘的,在空指針上調用'free'是合法的。 (另外,與基於循環for(const auto elem:l_list)''的範圍相比,幾乎純粹基於觀點但是'std :: for_each'似乎有點臃腫。 – George