[英]How to remove an item from a structure array in C++?
我具有以下数组结构(链接列表):
struct str_pair
{
char ip [50] ;
char uri [50] ;
str_pair *next ;
} ;
str_pair *item;
我知道要创建一个新项目,我需要使用
item = new str_pair;
但是,我需要能够遍历数组并删除特定项。 我有循环部分排序。 但是,如何从结构数组中删除项目?
您显示的不是struct
数组,而是包含数组( char
类型)的struct
的链表。
数组struct
如下所示:
str_pair array_of_structs[10];
// or:
str_pair* dynamically_allocated_array_of_structs = new str_pair[10];
如果确实有类似的内容,则无需从数组中delete
单个项目。 假设您已按照以下方式初始化了数组:
str_pair* array_of_structs = new str_pair[10];
然后,使用以下命令删除整个数组(包括其所有项):
delete[] array_of_structs;
同样,您不能delete
分配有new[]
的数组中的单个项目; 您对整个数组执行delete[]
。
另一方面,如果您打算说“ struct
链表 ”,那么通常将删除与以下内容类似的项目:
str_pair* previous_item = ...;
str_pair* item_to_delete = previous_item->next;
if (item_to_delete != 0)
{
previous_item->next = item_to_delete->next; // make the list "skip" one item
delete item_to_delete; // and delete the skipped item
}
或者,用英语:找到要删除的项目( B )之前的项目( A ),然后调整A的“下一个”指针,以便将B跳过列表,然后删除B。
您需要注意特殊情况 ,例如,要从列表中删除的项目是第一项还是最后一项。 当您要删除列表中的第一项时,上面的代码是不够的,因为将没有previous_item
。 在这种情况下,您需要将指向列表的第一个元素的指针更改为第二个元素。
void deleteitem(char *uri) { str_pair *itemtodelete; curr = head; while (curr->next != NULL) { if ((strcmp(curr->uri, uri)) == 0) { itemtodelete = curr; curr = itemtodelete->next; delete itemtodelete; curr = head; return; } curr = curr->next; } }
这里有些错误:
如果head
为null,则测试curr->next != NULL
将导致段错误。 (您绝不能取消引用空指针!)
您用于从列表中删除项目的代码是完全错误的。 最糟糕的是,您在不更改上一项的下一个指针的情况下删除了一个节点。 因此,上一项将引用不再存在的项。
详细信息: curr = head;
在return
语句之前根本没有任何用处。
分两步执行:一种功能是通过连接的uri
查找要删除的节点,另一种功能是删除节点。 您可以比下面的代码更好地分离它,但这应该是一个起点:
str_pair* finditemwithuri(char* uri)
{
str_pair* current = head;
while (current)
{
if (strcmp(current->uri, uri) == 0) return current;
current = current->next;
}
return 0;
}
void deleteitem(char* uri)
{
// find linked list node with that uri; abort if uri not in list
str_pair* itemtodelete = finditemwithuri(uri);
if (!itemtodelete) return;
// special case: node to be deleted is the list's head
if (itemtodelete == head)
{
head = itemtodelete->next;
delete itemtodelete;
return;
}
// else, iterate over list nodes
// up to the one preceding the node to be deleted
str_pair* current = head;
while (current)
{
if (itemtodelete == current->next)
{
current->next = itemtodelete->next;
delete itemtodelete;
return;
}
current = current->next;
}
}
只需使用std :: list。 没有理由手动编写这样的结构。
http://msdn.microsoft.com/zh-CN/library/802d66bt(VS.80).aspx
std :: list优惠已删除。
您可以使用普通的delete关键字将其删除,但这不会移动数组的所有其他成员。 如果您想要这种行为,请看一下std :: vector或类似的东西。
正如其他人指出的那样,这是一个链表,而不是数组。 要回答链表的问题:
要插入项目:
str_pair* p = // iterate over the linked list to your insertion point
str_pair* item = new str_pair;
item->next = p->next;
p->next = item;
这将在p之后插入新的str_pair
。
删除项目:
str_pair* p = // iterate to just before your deletion point
str_pair* item = p->next;
p->next = p->next->next;
delete item;
这将删除p
之后的元素
要使用您的代码执行此操作:
void deleteitem(char *uri)
{
str_pair *previous = NULL;
curr = head;
while (curr != NULL) {
if ((strcmp(curr->uri, uri)) == 0) {
// modify the previous element to skip over our deleted one
if (previous)
previous->next = curr->next;
else
head = curr->next;
// safely delete the element, now that no one points to it
delete curr;
curr = head;
return;
}
// always remember our previous element, so we can fix its 'next' pointer
previous = curr;
curr = curr->next;
}
}
您还需要更好的添加方法:
void additem(char *uri, char *ip)
{
curr = head;
// traverse the list until we're at the last item
while (curr->next != NULL) {
curr = curr->next;
}
// attach a new element to the list
curr->next = new str_pair;
// go to that new element
curr = curr->next;
// set the values of the new element
strcpy(curr->ip, ip);
strcpy(curr->uri, uri);
curr->next = NULL;
curr = head;
}
可能不在主题之列,但是为什么不使用std::list
库呢?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.