这是我关于链接列表的最后一个question的继续。我已经做了一些工作,我陷入了一些我需要实现的功能。我现在质疑的是destroy()函数。
应该释放每个list_项的内存。方法是从前到后递归删除每个list_item,直到找到NULL。但是由于某种原因,它只会从结构中删除键值。节点仍在那里。
这是代码 我在list_ destroy()中注释删除(my_ this)的原因是检查list_item是否被删除。
#include <iostream>
using namespace std;
struct list_item
{
int key; // identifies the data
double value; // the data stored
struct list_item* next; // a pointer to the next data
};
// Why do you need this? And why would you want it anyway?
struct my_list
{
struct list_item* first; // a pointer to the first element of the list
};
//+-----------------------------------------------------
//| Module: list_init
//| Description: Initiate the list to an empty list
//| Input: A pointer to the uninitialized list
//| Result: The list is empty
//| Conditions: Assumes the list is uninitialized
//+-----------------------------------------------------
void list_init(struct my_list* my_this)
{
// ADD YOUR CODE HERE (approx 1 line)
//set the list NULL at beginning
my_this->first = NULL;
}
//+-----------------------------------------------------
//| Module: list_add
//| Description: Insert a new key, value pair in a sorted list
//| Input: The list to insert in and the key, value to insert
//| Result: The list is sorted according to keys and include the
//| new key, value pair
//| Conditions: The list is assumed to be sorted before the insert
//| Duplicate keys are allowed. The order of duplicate
//| keys is undefined
//+-----------------------------------------------------
void list_add(struct my_list* my_this, int key, double value)
{
// ADD YOUR CODE HERE (approx 23 lines)
//create new list_item node
list_item* new_node;
//allocate memory to it
new_node = new list_item;
//adding values
new_node->key = key;
new_node->value = value;
if ( my_this->first != NULL)
{
new_node->next = my_this->first;
}
else
{
new_node->next = NULL;
}
my_this->first = new_node;
}
//+-----------------------------------------------------
//| Module: list_remove
//| Description: Remove the value with key from a sorted list
//| Input: The list to remove from and the key of the value to remove
//| Result: The list is sorted and do not contain a value with that key
//| Conditions: The list is assumed to be sorted before the insert
//| If duplicates of the key to remove exist only is removed.
//| It is undefined which of the duplicates that are removed.
//+-----------------------------------------------------
void list_remove(struct my_list* my_this, int key)
{
// ADD YOUR CODE HERE (approx 23 lines)
list_item *curr;
//allokera minne
curr = new list_item;
curr = my_this->first;
list_item *prev = new list_item;
for(int i=0; i<key;i++)
{
prev = curr;
curr = curr->next;
}
prev->next = curr->next;
delete(curr);
}
//+-----------------------------------------------------
//| Module: destroy
//| Description: First destroy any next list item, then release the
//| memory of the specified list item.
//| This will recursively destroy an list starting on this item.
//| Input: The list item to relese memory for (delete)
//| Result: The memory used by the list item, and any linked items,
//| are reclaimed by the OS
//| Further use of the list item is invalid
//| Conditions: The item is a pointer allocated with new and not
//| deleted before
//+-----------------------------------------------------
void destroy(struct list_item* item)
{
// ADD YOUR CODE HERE (approx 5 lines)
list_item *temp = new list_item;
if(item)
{
temp = item;
item = temp->next;
delete(temp);
destroy(item);
}
}
//+-----------------------------------------------------
//| Module: list_destroy
//| Description: Free the memory of an entire list.
//| Input: The list to destroy.
//| Result: All memory used by the list is reclaimed by the OS.
//| The list will become a valid but empty list.
//| Conditions: The list is initiated and valid.
//+-----------------------------------------------------
void list_destroy(struct my_list* my_this)
{
// ADD YOUR CODE HERE (approx 2 lines)
destroy(my_this->first);
// delete(my_this);
}
//+-----------------------------------------------------
//| Module: clone
//| Description: First create a new copy of the specified list
//| then append to the new item a clone of the next.
//| This will recursively create a copy of a entire
//| list starting on this item.
//| Input: The list item to clone.
//| Result: A copy of the specified item and any linked items.
//| Conditions: The item is valid.
//+-----------------------------------------------------
struct list_item* clone(struct list_item* item)
{
// ADD YOUR CODE HERE (approx 10 lines)
return item;
}
//+-----------------------------------------------------
//| Module: list_copy
//| Description: Copy an entire list
//| Input: The list to copy
//| Result: A new and valid list that are an independent copy
//| Conditions: The list is initiated and valid.
//+-----------------------------------------------------
struct my_list list_copy(struct my_list* my_this)
{
// ADD YOUR CODE HERE (approx 3 lines)
my_list *copy = new my_list;
copy = my_this;
return *copy;
}
struct my_iterator
{
struct list_item* current; // a pointer to the "current" list element
};
//+-----------------------------------------------------
//| Module: list_begin
//| Description:
//| Input:
//| Result:
//| Conditions:
//+-----------------------------------------------------
struct my_iterator list_begin(struct my_list* my_this)
{
struct my_iterator i;
i.current = my_this->first;
return i;
}
//+-----------------------------------------------------
//| Module: iterator_end
//| Description:
//| Input:
//| Result:
//| Conditions:
//+-----------------------------------------------------
bool iterator_end(struct my_iterator* i)
{
return i->current == NULL;
}
//+-----------------------------------------------------
//| Module: iterator_next
//| Description:
//| Input:
//| Result:
//| Conditions:
//+-----------------------------------------------------
void iterator_next(struct my_iterator* i)
{
i->current = i->current->next;
}
//+-----------------------------------------------------
//| Module: iterator_get_key
//| Description:
//| Input:
//| Result:
//| Conditions:
//+-----------------------------------------------------
int iterator_get_key(struct my_iterator* i)
{
return i->current->key;
}
//+-----------------------------------------------------
//| Module: iterator_get_value
//| Description:
//| Input:
//| Result:
//| Conditions:
//+-----------------------------------------------------
double iterator_get_value(struct my_iterator* i)
{
return i->current->value;
}
//+-----------------------------------------------------
//| Module: main
//| Description:
//| Input:
//| Result:
//| Conditions:
//+-----------------------------------------------------
int main()
{
// ADD YOUR CODE HERE (approx 50 lines)
my_list*list = NULL;
list = new my_list;
list_init(list);
//list->first = NULL;
int key = 0;
double value = 0;
int i =0;
while(i <5)
{
++i;
cin>> value;
value = (int) value;
key = (int) value;
list_add(list,key,value);
cout << "Adding" << endl;
}
// my_list *list2 = new my_list;
// list_init(list2);
// list2 = list_copy(list);
//destroy the list and its content
list_destroy(list);
list_remove(list, 3);
cout << endl << "Print list" << endl;
for(my_iterator i = list_begin(list); !iterator_end(&i); iterator_next(&i))
{
cout << iterator_get_key(&i) << " " << iterator_get_value(&i) << endl;
}
list_destroy(list);
cout << endl << "Print list" << endl;
for(my_iterator i = list_begin(list); !iterator_end(&i); iterator_next(&i))
{
cout << iterator_get_key(&i) << " " << iterator_get_value(&i) << endl;
}
// list_destroy(list2);
return 0;
}
答案 0 :(得分:2)
确定。您不应该在destroy函数中分配新的列表项。 相反,我会这样做:
void destroy(struct list_item* item)
{
// ADD YOUR CODE HERE (approx 5 lines)
if(item)
{
list_item *temp = item;
item = temp->next;
delete temp;
destroy(item);
}
删除操作符不是函数,因此您可以不使用括号。 作为递归函数执行此操作也有点不寻常。这没有错,但让代码更像是更为正常:
void destroy(struct list_item* item)
{
// ADD YOUR CODE HERE (approx 5 lines)
while(item)
{
list_item *temp = item;
item = temp->next;
delete temp;
}
答案 1 :(得分:1)
destroy()
函数的主要内容几乎是正确的 - 唯一真正的错误是写入new list_item
的{{1}}的分配,如果{{1}则一次覆盖参数不是temp
。为什么您在调用item
时不会删除列表项? (注意:NULL
调用指针未设置为delete
,但指向的对象仍然被删除。)请澄清!
NULL
错误,因为delete
的嵌套调用太多了。最好使用循环。
答案 2 :(得分:1)
删除所有节点后,需要将first
指针设置为NULL。由于您没有这样做,因此您的代码在destroy
操作后访问已释放的内存。
答案 3 :(得分:0)
以下应该可以解决问题:
void destroy(struct list_item* item)
{
struct list_item *temp;
while (item)
{
temp = item;
item = temp->next;
delete(temp);
}
}
或者如果您更喜欢递归解决方案:
void destroy(struct list_item* item)
{
if (item) {
destroy(item->next);
delete(item);
}
}