我正在嘗試撰寫我自己的 malloc 并在 C 中為一個專案免費。在大多數情況下,一切都很好,但我無法解決它給我的奇怪的分段錯誤。我以簡化的形式復制了給出錯誤的代碼:
#include <stdio.h>
#define MEMORY_SIZE 4096
static char memory[MEMORY_SIZE];
typedef struct metaData{
unsigned short isFree; //1 if free, 0 if allocated
unsigned short size;
} metaData;
int main(){
metaData *head = (metaData *) memory;
printf("%d\n", (head 2031)->size);
printf("%d\n", (head 2032)->size);
puts("Segmentation up here???");
return 0;
}
memory是一個大小為 4096 的靜態字符陣列。第一個printf列印出 0。但下一個printf是段錯誤。我能夠metaData在每個指標處操作結構,直到head 2032. 有誰知道為什么?
uj5u.com熱心網友回復:
C 中的指標運算以指向型別大小的基本單位執行。你head是一個指向metaData結構的指標,它的大小為2 × sizeof(unsigned short). 假設(很可能,但不確定) anunsigned short在您的平臺上的大小為 2 個位元組,那么“基本單位”將是 4 個位元組。
因此,當進行head 2031計算時,4 × 2031(即 8124)的值將被添加到地址 inhead以給出該運算式的結果。因此,使用以下->size運算子,您嘗試從陣列開頭的位置參考 8,126 位元組1memory的記憶體- 但該陣列被宣告為僅4096 位元組(sizeof(char)根據定義,1 位元組)。
訪問超出陣列宣告大小的記憶體是未定義行為(UB);一旦你呼叫了這樣的 UB(就像你在兩個 printf呼叫中所做的那樣),許多不同的事情就會發生,并且以不可預知的方式發生。“分段錯誤”(試圖讀取或寫入您的程式無權訪問的記憶體)是 UB 的一種可能表現形式。(另一種可能的表現是沒有報錯,程式似乎運行正常;在很多人看來,這是最糟糕的一種!)
1 8,124 位元組將是潛在指向meteData結構的開始的偏移量;因為size前面有另一個unsigned short成員,所以會添加另外兩個位元組。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/434172.html
上一篇:C中的指標轉換
下一篇:為什么我必須使用二維陣列?
