Ошибка компиляции dereferencing pointer to incomplete type ‘queue_t’
возникает в результате разыменования указателя на queue_t
в main
, который является непрозрачным типом непрозрачного типа AKA.
API в queue.h
предназначен для скрытия определения структура queue_t
от звонящего. Вызывающие функции должны использовать указатель только на эту структуру. Таким образом, вызывающий объект не должен знать, что существует структурное поле size
.
. Чистым способом решения этой проблемы является добавление функции getter в API для возврата запрошенного значения. Функция должна быть объявлена в queue.h
и реализована в queue.c
, например
int get_size(queue_t *queue)
{
int size = -1; /* error return value */
if(queue != NULL)
{
size = queue->size;
}
return size;
}
(В качестве хака вы можете добавить копию определения структуры в main.c
. Я не t рекомендую это. )
Чтобы проверить ошибку сегментации, я скомпилировал программу с помощью
gcc -Wall -Wextra -pedantic main.c queue.c -o main
Запуск программы с valgrind
как
valgrind ./main
Я получаю несколько сообщений об ошибках
==25539== Memcheck, a memory error detector
==25539== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25539== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==25539== Command: ./main
==25539==
First node added had value 42
==25539== Invalid read of size 4
==25539== at 0x1092FC: dequeue (queue.c:45)
==25539== by 0x109200: main (main.c:14)
==25539== Address 0x4a5a0e8 is 8 bytes inside a block of size 16 free'd
==25539== at 0x483BA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x1093AE: dequeue (queue.c:60)
==25539== by 0x1091E1: main (main.c:13)
==25539== Block was alloc'd at
==25539== at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x10926D: enqueue (queue.c:25)
==25539== by 0x1091C4: main (main.c:10)
==25539==
==25539== Invalid read of size 8
==25539== at 0x109359: dequeue (queue.c:54)
==25539== by 0x109200: main (main.c:14)
==25539== Address 0x4a5a0e0 is 0 bytes inside a block of size 16 free'd
==25539== at 0x483BA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x1093AE: dequeue (queue.c:60)
==25539== by 0x1091E1: main (main.c:13)
==25539== Block was alloc'd at
==25539== at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x10926D: enqueue (queue.c:25)
==25539== by 0x1091C4: main (main.c:10)
==25539==
==25539== Invalid read of size 8
==25539== at 0x109382: dequeue (queue.c:57)
==25539== by 0x109200: main (main.c:14)
==25539== Address 0x4a5a0e0 is 0 bytes inside a block of size 16 free'd
==25539== at 0x483BA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x1093AE: dequeue (queue.c:60)
==25539== by 0x1091E1: main (main.c:13)
==25539== Block was alloc'd at
==25539== at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x10926D: enqueue (queue.c:25)
==25539== by 0x1091C4: main (main.c:10)
==25539==
==25539== Invalid free() / delete / delete[] / realloc()
==25539== at 0x483BA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x1093A2: dequeue (queue.c:59)
==25539== by 0x109200: main (main.c:14)
==25539== Address 0x4a5a0e0 is 0 bytes inside a block of size 16 free'd
==25539== at 0x483BA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x1093AE: dequeue (queue.c:60)
==25539== by 0x1091E1: main (main.c:13)
==25539== Block was alloc'd at
==25539== at 0x483A7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==25539== by 0x10926D: enqueue (queue.c:25)
==25539== by 0x1091C4: main (main.c:10)
==25539==
Second node added had value 43
==25539==
==25539== HEAP SUMMARY:
==25539== in use at exit: 16 bytes in 1 blocks
==25539== total heap usage: 5 allocs, 5 frees, 1,088 bytes allocated
==25539==
==25539== LEAK SUMMARY:
==25539== definitely lost: 16 bytes in 1 blocks
==25539== indirectly lost: 0 bytes in 0 blocks
==25539== possibly lost: 0 bytes in 0 blocks
==25539== still reachable: 0 bytes in 0 blocks
==25539== suppressed: 0 bytes in 0 blocks
==25539== Rerun with --leak-check=full to see details of leaked memory
==25539==
==25539== For lists of detected and suppressed errors, rerun with: -s
==25539== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Очевидно, у вас уже есть free
da-узел в функции dequeue
в строке 60
free(cur);
, и вы получаете доступ к этому узлу в строке 45
int tbr = q->tail->value; //value to be returned
и строка 54
cur = cur->next;
и строка 57
cur->next = old->next;
Затем в строке 59 вы пытаетесь free
этот блок снова
free(old);
Путем добавления отладки printf
s при вводе и возврате enqueue
и dequeue
я обнаружил, что первый вызов dequeue
не приводит к ошибке и возвращает в else
филиал. Ошибки возникают во втором вызове dequeue
, который также возвращается в ветке else
. Видимо, при первом вызове dequeue
вы free
узел, который будет использоваться, и free
d во втором вызове.
Я не анализировал вашу программу подробно, но, думаю, это неправильно free
и old
и cur
в dequeue
.
Запускать программу шаг за шагом, используя отладчик, и подумать о том, как узлы вашего списка связаны и когда вам нужно free
какой узел.