Допустим, у меня есть реализация списка, который использует следующие listnode_t
:Разграничение памяти стека и кучи
typedef struct ListNode {
struct ListNode *next;
struct ListNode *prev;
void *value;
} listnode_t;
Это вдвойне связанный список А, как вы можете видеть. У меня также есть list_t
, которые имеют два указателя на listnode_t
как первый и последний узел и размер списка. Теперь я предполагаю следующее в моем основной
int main(int argc, char *argv[]){
...
// Create two empty lists
list_t *list1 = make_list();
list_t *list2 = make_list();
// Populate one with ints
int x = 4;
int y = 5;
list_push(list1, &x);
list_push(list1, &y);
// Populate other with strings
string_t *str1 = make_string("foo");
string_t *str2 = make_string("bar");
list_push(list2, str1);
list_push(list2, str2);
...
// Delete at the end
destroy_list(list1);
destroy_list(list2);
}
У меня есть проблема с реализацией destroy_list
. Вот что я пробовал;
void destroy_list(list_t *list)
{
listnode_t *cur = list -> first;
for(cur = list -> first; cur != NULL; cur = cur -> next){
if(cur -> prev){
free(cur -> prev);
}
}
free(list -> last);
free(list);
list = NULL;
}
Моя проблема заключается в том, что я пытаюсь использовать void *
в listnode_t
, чтобы иметь возможность использовать этот список в общих чертах. Но когда я удаляю вещи, применение free(cur -> prev)
кажется проблематичным. Когда я использую список таких вещей, как ints, как указано выше, поскольку они выделены в стеке, все идет хорошо, я думаю. Но если бы у меня был список строк, как указано выше, поскольку я использую динамическое распределение в моей реализации строки, я должен сначала применить free(cur -> prev -> value)
. Я не знаю, как это сделать, потому что, если я его добавлю, у меня возникает другая проблема с попыткой освободить выделенную стекю память на главном.
Что мне делать, я не получаю это общее поведение в списке.
Пользователь должен предоставить функцию для уничтожения 'value', поскольку только пользователь списка знает, что хранится и что нужно сделать. Поэтому 'make_list' должен указывать в качестве параметра функцию для уничтожения значения. –
Protip: никогда не когда-либо когда-либо когда-либо когда-либо когда-либо когда-либо использовал связанный список. Связанный список принадлежит стенам университетского городка, нигде больше. –
Каково определение list_t? – levengli