Красный флаг здесь означает, что &request_ctx
является адресом локальной переменной.Это не указатель на хранилище, выделенное с помощью malloc
, а адрес переменной, которая содержит это хранилище.Эта переменная исчезает после завершения этой области действия, даже если срок действия блока malloc
.
Возможно, исправление заключается в простом удалении оператора address-of &
в этой строке?
steque_item work_item = &request_ctx; // steque_item is a void* so passing
// it a pointer to the Request_work_item
Если мы сделаем это, то комментарий на самом деле говорит правду.Потому что в противном случае мы создаем work_item
a указатель на указатель на Request_work_item
.
Поскольку work_item
имеет тип void
*, он компилируется в любом случае, к сожалению.
Если потребитель элемента на другом конце очереди извлекает его как Request_work_item *
, то у вас есть не только доступ к объекту, который вышел из области видимости, но и несоответствие типовдаже если этот объект все еще находится в области действия производителя, когда его использует потребитель.Потребитель заканчивает тем, что использует часть стека производителя, как если бы это была структура Request_work_item
. Редактировать: Я вижу, что вы используете указатель-указатель при снятии очереди с элемента и обращаетесь к нему как (*wi)->path
.Подумайте об изменении дизайна, чтобы избежать этого.Или же указатель wi
также должен быть динамически размещен и освобожден.Производитель должен сделать что-то вроде:
struct Request_work_item **p_request_ctx = malloc(sizeof *p_request_ctx);
struct Request_work_item *request_ctx = malloc(sizeof *request_ctx);
if (p_request_ctx && request_ctx) {
*p_request_ctx = request_ctx;
request_ctx->field = init_value;
// ... etc
// then p_request_ctx is enqueued.
Потребитель затем должен free
структуру, а также free
указатель.Этот дополнительный указатель здесь выглядит просто как накладные расходы;он не обеспечивает какого-либо существенного или полезного уровня косвенности.