[英]Segmentation fault and dereferencing pointer
我正在為學校做一個項目,我必須實現一個隊列。 我在 main.c 文件中編寫了一些非常簡單的測試,看看是否一切正常,但是我遇到了兩個我不知道如何修復的錯誤,我可能需要你們的幫助!
我得到的第一個錯誤是Segmentation fault (core dumped)
。 我知道這與內存訪問問題有關,但老實說我不知道我做錯了什么。 有沒有一種簡單的方法來調試 c 中的段錯誤?
順便說一句,當我取消注釋 main.c 的第 9 行時
printf("One node added, size = %d\n",my_queue->size);
我收到另一條錯誤消息:
main.c: In function ‘main’:
main.c:9:47: error: dereferencing pointer to incomplete type ‘queue_t’ {aka ‘struct queue’}
9 | printf("One node added, size = %d\n",my_queue->size);
| ^~
我發現當您嘗試取消引用尚未定義(或聲明)的結構時會發生此錯誤。 這條消息讓我感到驚訝,因為我確實在頭文件 queue.h 中聲明了我的類型 queue_t 並且我確實在我的 queue.c 文件中定義了它。
你可以在這個repo上找到我正在談論的所有文件
非常感謝您的幫助,祝您有美好的一天!
迭戈
dereferencing pointer to incomplete type 'queue_t'
的編譯錯誤是由於dereferencing pointer to incomplete type 'queue_t'
main
指向queue_t
的指針而導致的, main
是不完整的類型 AKA 不透明類型。
queue.h
的 API 旨在對調用者隱藏結構queue_t
的定義。 調用函數應該只使用指向該結構的指針。 所以調用者不應該知道有一個結構字段size
。
解決這個問題的干凈方法是向 API 添加一個 getter 函數以返回請求的值。 該函數應該在聲明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
。我不推薦這樣做。 )
為了檢查分段錯誤,我編譯了程序
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)
顯然你已經在第 60 行的函數dequeue
中free
da 節點
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);
通過在入enqueue
和dequeue
的入口和返回處添加 debug printf
s,我發現對dequeue
的第一次調用不會導致錯誤並在else
分支中返回。 錯誤發生在對dequeue
的第二次調用中,該調用也在else
分支中返回。 顯然,在第一次dequeue
調用中,您free
了一個將被使用的節點,並在第二次調用中free
d。
我沒有詳細分析你的程序,但我想在dequeue
free
old
和cur
是錯誤的。
使用調試器逐步運行您的程序,並考慮列表中的節點是如何連接的以及何時必須free
哪個節點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.