如何为队列释放内存?我不自由

时间:2011-11-12 04:35:24

标签: c++ queue free

这是修订版。

需要3.5GB内存,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 个答案:

答案 0 :(得分:2)

如果您使用的是c++,则应使用标准库中的queue<T>。以下是参考:http://www.cplusplus.com/reference/stl/queue/

对于c ++代码,除非绝对必要,否则不应编写自己的容器类。标准库提供了许多有用的容器,涵盖了大多数用例。它们经过大量使用和测试,已存在多年。

答案 1 :(得分:0)

即使是空的队列结构仍然会使用内存。我假设您已将队列定义为

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

因此,空队列仍然需要内存来存储headtail指针,即使它们都是NULL

你如何“测量”内存使用情况?显然sizeof并不好,因为它只是struct queue的恒定大小。所以我假设你有一些其他工具或代码正在测量它。但代码看起来还不错,并且正如你所期望的那样释放内存。

你遇到的一个问题是,dequeue函数永远不会设置tail。但是如果head在设置为head->next后为NULL,那么您还需要将tail设置为NULL。不要以为这会导致内存泄漏,但如果你在队列排队后排队,那么肯定会让你陷入腐败或段错误。

答案 2 :(得分: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 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表示为非零,false表示为0. ==运算符的结果保证是这样的,因此强制为1无效;

return q->head == NULL;

最后要注意的是:在某些系统上,top等程序读出的“使用的内存”可能不会消失。这是因为系统保留了已释放内存的页面以供将来使用。它可能会释放物理内存,但虚拟内存地址将保留为程序的“可用”,直到终止。