假设我有一个双向链表,例如
class list
{
/*...*/
private:
struct node
{
node* prev;
node* next;
int* value;
}
node* first; //NULL if none
node* last; //NULL if none
/*...*/
}
如果我想编写一个删除第一个节点的函数并返回指向其值的指针,那么这个实现是否会泄漏内存?
int* returnFrontValue()
{
if(list_is_Empty())
throw -1;
else
{
node* v = first;
int* returnMe = v->value;
first = first->next;
if(!first)
last = NULL;
delete v;
first->prev = NULL;
return returnMe;
}
}
我很好奇这个实现是否会泄漏内存,因为returnMe
指向动态分配的int。最后有一个int returnMe = *(v->value);
并最后返回&returnMe;
吗?
我delete v->value;
之前是否必须明确delete v;
?当你有各种各样的指针时,我对如何删除内存感到困惑。
答案 0 :(得分:2)
我们无法看到int
是如何分配的,但我会接受它的动态分配(作为您删除的节点的单独分配)。
在那种情况下没有,你还没有泄露任何然而,但你是诱人的命运。这不是泄漏,因为指向int
的指针仍然存在,因此仍然可以删除它。但现在责任在于呼叫者。如果我调用returnFrontCaller
,我会得到一个指向值的指针,然后当我完成它时,我必须调用delete
。
这不是很直观。通常new
/ delete
来电应在同一个地方进行匹配。如果我致电new
,我也会致电delete
。如果new
来电在其他地方发生,我不希望拨打delete
是我的责任。
但为什么在所有Why do you store an
int * instead of an
int`中动态分配值?为什么函数返回指向int的指针而不是它的副本?
如果您进行了更改,则无需进行内存管理。调用者将获得一个int,并且不必担心“谁调用delete
”。
或者,您可以使用智能指针类来包装它,并处理内存管理。