Как освободить память для очереди?Шахта не свободна - PullRequest
0 голосов
/ 12 ноября 2011

Это исправленная версия.

Требуется 3,5 ГБ памяти, а функция pop не освобождает память ... Как я могу использовать new и delete, чтобы вернуть эту память? Сейчас я использую STL. поскольку new и delete работают только для указателей?

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;

Ответы [ 3 ]

2 голосов
/ 12 ноября 2011

Если вы используете c++, вы должны использовать queue<T> из стандартной библиотеки. Вот ссылка: http://www.cplusplus.com/reference/stl/queue/.

Для кода на С ++ вы никогда не должны писать свои собственные контейнерные классы, если это не является абсолютно необходимым. Стандартная библиотека предоставляет множество полезных контейнеров, которые охватывают большинство случаев использования. Они интенсивно используются и испытаны, и были в течение многих лет.

0 голосов
/ 12 ноября 2011

Ваша очередь может очиститься после себя, если и только если 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;

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

In dequeue:

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

else не требуется, поскольку первая часть всегда return s.

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. Результат оператора == гарантированно будет таким, поэтомунет смысла заставлять true быть 1;

return q->head == NULL;

Последнее замечание: в некоторых системах «используемая память», считываемая такой программой, как top, может не уменьшаться.Это связано с тем, что система хранит страницы освобожденной памяти для дальнейшего использования.Это может освободить физическую память, но адреса виртуальной памяти будут оставаться «доступными» для вашей программы до завершения.

0 голосов
/ 12 ноября 2011

Даже пустая структура очереди все еще будет использовать память. Я предполагаю, что вы определили очередь как что-то вроде

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

Таким образом, для пустой очереди по-прежнему потребуется память для хранения указателей head и tail, даже если они оба NULL.

Как вы "измеряете" использование памяти? Очевидно, что sizeof не годится, так как это будет просто постоянный размер struct queue. Поэтому я предполагаю, что у вас есть какой-то другой инструмент или код, который его измеряет. Но код выглядит нормально для меня, и он должен освободить память, как вы ожидаете.

Одна ошибка, которую вы имеете, заключается в том, что функция dequeue никогда не устанавливает tail. Но если head равно NULL после установки его в head->next, то вам также нужно установить tail в NULL. Не думайте, что это приведет к утечке памяти, но определенно может привести к повреждению или segfault, если вы ставите в очередь после того, как очередь удаляет очередь.

...