我有一个包含以下成员的类String:
Class String{
...
private:
char* word
int length
}
String的复制赋值返回String&并在堆上分配单词。
我还有一个用C编写的链表类,它有一个函数:
void *popFront(struct List *list)
{
struct Node prevHead = list->head
list->head = prevHead->next;
void *info = prevHead->info;
free(prevHead);
return info;
}
我的任务是为使用C函数的C ++链表编写相同的函数。这就是我所拥有的:
String List::popFront()
{
String s = (*(String *) ::popFront(&list));//casting the void * to String
return s;
}
C ++方法应该按值返回对象。这就是我认为该方法会做的事情。然而, 我得到了内存泄漏。有关如何修改List :: popFront()以便按值返回的任何提示?感谢。
答案 0 :(得分:1)
首先将返回的指针本地存储为指向字符串的指针,然后创建字符串的本地副本,然后删除对象,指针指向并最终返回本地副本。
编辑: 顺便说一句。您可以使用c ++ 11的智能指针来避免额外的副本:
String List::popFront()
{
auto s = std::unique_ptr<String>((String*) ::popFront(&list));
return *s;
}
但这可能不是,老师的目标。
答案 1 :(得分:0)
您声明String List::popFront()
,它返回一个对象,而不是一个指针。 String s = ...
声明一个对象,而不是指针或引用。因此,为s
值构建新对象s
作为::popFront
返回的副本,然后是下一个返回s
的{/ em>,并且s
本身会被销毁。但是,由::popFront()
取消链接的对象仍然在堆上,从而导致泄漏。
不要创建String
对象的中间副本,将指针返回到未链接的对象,以便调用者可以在使用后将其链接到自己的列表或delete
:
String *List::popFront()
{
String *s = (String *) ::popFront(&list);//casting the void * to String *
return s;
}
答案 2 :(得分:0)
popFront
从链接列表中删除元素并释放节点,但不释放info
部分。这是popFront
来电者的责任,例如
String *s = (String *) ::popFront(&list);
delete s;
但是你还必须保留一份副本,你可以从方法
返回String List::popFront()
{
String *s = (String *) ::popFront(&list);
String tmp = *s;
delete s;
return tmp;
}