2011-11-12 105 views
-1

這是修改後的版本。如何爲隊列釋放內存?礦不免費

它需要3.5GB的內存和彈出功能不釋放內存......我如何使用新的和刪除來恢復這些內存?現在我正在使用STL。因爲新增和刪除只適用於指針?

queue<Graphnode> ss; 
    for(i=0;i<30000000;i++) 
    { 
     ss.push(*g.root); 
    } 

    printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"); 
     for(i=0;i<30000000;i++) 
    { 
     ss.pop(); 
    } 
    printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"); 
    //delete &ss; 

這裏是我的node.h文件。我想我需要malloc和free或new,在這裏刪除指針?

#include <stdio.h> 
#include <stdlib.h> 
#include <tr1/array> 

typedef struct point 
{ 
    std::tr1::array<int, 16> state; 
    int x; 
}point; 
typedef struct Graphnode 
{ 
    struct point pvalue; 
    int depth; 
    struct Graphnode *up; 
    struct Graphnode *down; 
    struct Graphnode *left; 
    struct Graphnode *right; 
}Graphnode; 

所以修改後的代碼應該看起來像這樣?

#include <stdio.h> 
#include <stdlib.h> 
#include <tr1/array> 

typedef struct point 
{ 
    std::tr1::array<int, 16> state; 
    int x; 
    int depth; 
}point; 
typedef struct Graphnode 
{ 
    point *pvalue = (point *)malloc(sizeof(point)); 
    Graphnode *up = (Graphnode*)malloc(sizeof(Graphnode)); 
    Graphnode *down= (Graphnode*)malloc(sizeof(Graphnode));; 
    Graphnode *left= (Graphnode*)malloc(sizeof(Graphnode));; 
    Graphnode *right= (Graphnode*)malloc(sizeof(Graphnode));; 
}Graphnode; 
+0

您應該添加「push」函數的代碼,以及如何創建隊列的元素。你用'C++'標記了你的問題,但你試圖使用'free'。 –

+0

對不起,這是爲隊列不堆棧。我改變了這一點。我想知道C中的free()函數有什麼功能? – weeo

+0

有'delete'運算符。請參閱http://www.cplusplus.com/reference/std/new/operator%20delete/。如果你用'new'分配對象,你應該使用'delete'。另外,在常規的C++標準庫中,您可以使用'push_front()'或'push_back()'將元素添加到容器的頭部和尾部,因此可以命名。 –

回答

3

如果您使用c++,你應該使用queue<T>從標準庫。以下是參考:http://www.cplusplus.com/reference/stl/queue/

對於C++代碼,除非絕對必要,否則不應編寫自己的容器類。標準庫提供了許多有用的容器,覆蓋了大多數用例。它們被大量使用和測試,並且已經使用了很多年。

+0

如果使用std :: deque作爲基礎容器,則內存不斷增長。 – Etherealone

0

即使是空的隊列結構仍然會使用內存。我假設你已經定義的隊列,就像這樣

struct queue 
{ 
    queueElement* head; 
    queueElement* tail; 
}; 

所以空隊列中仍然需要內存來存儲headtail指針,即使他們都NULL

你是如何「測量」內存使用量的?顯然sizeof是不好的,因爲它只是struct queue的恆定大小。所以我假設你有其他工具或代碼正在測量它。但是代碼對我來說看起來不錯,並且可以按照您的期望釋放內存。

你有一個錯誤是出列函數從不設置tail。但是如果head在將其設置爲head->next後爲NULL,那麼您還需要將tail設置爲NULL。不要認爲這會導致內存泄漏,但是如果在出隊隊列清空隊列之後入隊,則肯定會打開您的腐敗或段錯誤。

+0

我正在使用系統監視器來監視它。我修改了代碼以顯示我是如何做到的....感謝您的幫助,.... !! – weeo

0

當且僅當struct Graphnode是自包含的並且不包含指向已分配內存的指針時,您的隊列可以自行清理。

void emptyQueue(struct queue *q) { 
    queueElement *element, *nextElement; 
    element = q->head; 
    while(element) { 
     nextElement = element->next; 
     free(element); 
     element = nextElement; 
    } 
    initQueue(q); 
} 

注意,因爲initQueue沒有malloc,其對應的功能,emptyQueue,不應該free。這允許您在需要時在堆棧上創建隊列。

如果你的struct Graphnode有分配內存的指針,那麼你需要手工完成,而不是在emptyQueue。你的代碼看起來是這樣的:

struct Graphnode node; 
while(!isEmpty(q)) { 
    node = front(q); 
    /* Delete the stuff in `node` here. */ 
    dequeue(q); 
} 

你的C代碼一些評論...

enqueue您有:

if (q->head == NULL) { 
    //first element 
    q->head = newElement; 
    q->tail = newElement; 
} else { 
    //put it to the tail 
    q->tail->next= newElement; 
    q->tail = newElement; 
} 

既然你在兩條路徑做q->tail = newElement;,將其移出:

if (q->head == NULL) { 
    //first element 
    q->head = newElement; 
} else { 
    //put it at the tail 
    q->tail->next= newElement; 
} 
q->tail = newElement; 

此外,一致的縮進是一個好習慣。你的文本編輯器應該讓你更容易。

dequeue:不需要

if (q->head == NULL) { 
    //empty queue 
    return; 
} else { 
    element = q->head; 
    q->head = q->head->next; 
    free(element); 
} 

else,由於第一部分總是return秒。

if (q->head == NULL) { 
    //empty queue 
    return; 
} 
element = q->head; 
q->head = q->head->next; 
free(element); 

最後,在ifEmpty

return (q->head == NULL ? 1:0); 

C表示爲非零真假爲0。==操作的結果是保證是這樣的,所以沒有一點迫使真要1;

return q->head == NULL; 

最後一點:在某些系統中,「使用的內存」讀出的程序一樣top可能不下去。這是因爲系統正在保留已釋放內存的頁面供將來使用。它可能會釋放物理內存,但虛擬內存地址將保留在程序的「可用」範圍內,直到終止。

+0

非常感謝您的大力幫助!我已經使用STL修改了代碼。所以我需要重做我的Graphnode在那裏有新的和刪除? – weeo

+0

首先告訴我爲什麼Graphnode中的'point'是從堆中分配的。爲什麼它不是直接存儲在'Graphnode'中? –