Я уже прочитал несколько ответов, заданных для подобных вопросов, но есть одна вещь, которая делает мой случай немного отличным от того, что я читал. Я использую связанный список для хранения данных для потоков для выбора и обработки. Узел представляет собой простой typedef
Правильно освобожденная динамически распределенная структура
struct QueueNode;
typedef struct QueueNode {
struct QueueNode* next; // pointer to the next node
void* data;
} QueueNode;
В списке
typedef struct LinkedQueue {
QueueNode* head; // pointer to the first Node
QueueNode* tail; // pointer to the last Node
long long k; // the number of nodes in the queue
} LinkedQueue;
Оба инициализируются соответствующие функции, которые используют malloc
. Когда поток нуждается в обработке данных, он вызывает одну функцию, которая выталкивает голову очереди и возвращает указатель void* data
.
void* pop_data(LinkedQueue* queue) {
/*
Pops the head node from a queue, extracts data out of it and
frees the memory allocated by that node
*/
assert(queue->head && "Can't pop data from an empty queue");
void* data = queue->head->data; // extract data from head
QueueNode* old_head_pointer = queue->head;
queue->head = queue->head->next; // replacing head with a new one
destroy_node(old_head_pointer); // destroying the old head
return data;
};
Дело в том, что destroy_node
предполагается освободить память, выделенную для узла, не разрушая void* data
указатель, так как данные используются в дальнейшем. Это было моим делом. Все примеры, которые я уже прочитал, описывают случай полного освобождения всего внутри узла, в то время как мне нужно сохранить этот указатель.
void destroy_node(QueueNode* node) {
/*
Frees memory allocated by a node.
*/
free(node->next);
free(node);
};
В моих тестах это работает отлично, но так как я знаю, что free()
фактически не стереть часть памяти и поскольку моя машина имеет тонны памяти тот факт, что я все еще могу получить доступ, что void* data
указателя без сегментации на ошибки нельзя полагаться. Таким образом, в основном вопрос заключается в том, что я делаю это правильно или мои соображения действительно разумны? Если это действительно может привести к утечкам памяти или другим проблемам, связанным с памятью, как я должен это делать?
Использование кода вы показываете, вы освобождаете новый 'head' указатель. Не освободите 'node-> next'. –
'struct QueueNode' является неполным типом во всем этом коде ... Возможно, это неконфликтная ошибка, но ошибка, тем не менее, особенно если вы попытаетесь разыменовать« следующий »элемент. Могу ли я предложить вставить 'QueueNode' непосредственно после' typedef struct'? – Sebivor
Фактически это определяется как 'typedef struct QueueNode {...' в реальном коде, но я ценю примечание. –