То, что вы показали, это не массив struct
, а связанный список struct
, содержащий массивы (типа char
).
Массив из 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
}
Или по-английски: найдите элемент ( A ), предшествующий элементу, который вы хотите удалить ( B ), затем настройте A 's' следующий «указатель», так что 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
равно нулю, проверка 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;
}
}