Привет, у меня есть небольшая проблема с void *, используемым для того, чтобы сделать код более общим. Я написал очередь fifo (используя связанный список внизу), в которой хранятся любые данные, которые можно преобразовать в void * (т.е. struct * as void *).
Теперь у меня есть функция, которая извлекает эти данные обратно. Но проблема в том, что структура с 3 полями возвращается с заполненным только первым полем, а остальные 2 пустыми (были заполнены при помещении в очередь).
Все функции, такие как back(), unwrap'_data_from_node'() и fifo_dequeue(), возвращают эти данные как void *. Что более странно, так это то, что void * может быть приведен к struct * в fifo_dequeue(), и он будет содержать все поля, заполненные данными, в то время как при возврате из fifo_dequeue() тот же возвращаемый указатель имеет только одно заполненное поле (1-е поле), и два пустые, ноль.
void *fifo_dequeue(fifo_queue_t *fifo, size_t *data_size) {
doubly_linked_node_t *node;
size_t tmp_size;
void *tmp_data;
void *data;
// get data and its size from the last node in the queue
if((node = back(fifo->queue)) == NULL) {
fprintf(stderr, "back: queue is empty!\n");
data_size = NULL;
return NULL;
};
tmp_data = unwrap_data(node, &tmp_size);
/** HERE I tested casting data to struct test_t and it works properly **/
task_t *task;
task = (task_t *) tmp_data;
int task_size = sizeof(task);
// copy retrieved data
data = malloc(tmp_size);
memcpy(data, tmp_data, tmp_size);
// remove the last node in the queue
//pop_back(fifo->queue);
if(data_size != NULL) *data_size = tmp_size; // return size of data through pointer argument
return data; /** OUTSIDE this pointer casted to struct task_t has empty fields **/
}
Базовый метод удаления узла из связанного списка при выполнении pop_back();
void remove_node(doubly_linked_list_t *list, doubly_linked_node_t *old_node) {
// if node to delete unspecified return error
if (old_node == NULL) {
fprintf(stderr, "Node to delete is empty!");
return;
}
// if node to delete is the only left on the list make empty list
if (old_node->next == old_node) // or old_node->prev = old_node
{
list->head = list->tail = NULL;
} else {
old_node->prev->next = old_node->next;
old_node->next->prev = old_node->prev;
if(old_node == list->head) list->head = old_node->next;
if(old_node == list->tail) list->tail = old_node->prev;
}
free(old_node->data); old_node->data = NULL;
free(old_node); old_node = NULL;
}
int task_size = sizeof(task)
‹-- это не может быть правильным:sizeof *task
я думаю, что вы хотите, и во всяком случае:sizeof
возвращаетsize_t
, а неint
. Такжеtask_t *task; task = (task_t *) tmp_data;
выглядит некрасиво. Почему бы и нетtask_t * task = tmp_data;
. Актерский состав не нужен. Это чистый, легко читаемый однострочник - person Elias Van Ootegem   schedule 02.08.2016