2012-01-01 87 views
4

可能重複:
Invalid read/write sometimes creates segmentation fault and sometimes does not爲什麼運行這不會產生分段錯誤?

我有以下代碼:

#include <stdlib.h> 
#include <stdio.h> 

int main() { 
    int *ptr = NULL; 
    ptr = malloc(sizeof(char)); 
    if (ptr) { 
     *ptr = 10; 
     printf("sizeof(int): %zu\nsizeof(char): %zu\n", sizeof(int), sizeof(char)); 
     printf("deref of ptr: %d\n", *ptr); 
     free(ptr); 
     return EXIT_SUCCESS; 
    } 
    else 
     return EXIT_FAILURE; 
} 

當我編譯並運行它,我得到以下輸出:

$ gcc test.c 
$ ./a.out 
sizeof(int): 4 
sizeof(char): 1 
deref of ptr: 10 

sizeof(char)小於sizeof(int)。我的malloc呼叫只留出足夠的空間用於char。但是,我的程序能夠在不崩潰的情況下爲ptr分配一個整數值。爲什麼這個工作?

+1

你可能想看看這個問題及其答案的指導:http://stackoverflow.com/questions/8641478/invalid-read -write-sometimes-creating-segmentation-fault-and-sometimes-does-not – 2012-01-01 21:58:16

+0

C不一定會遵守變量'boundries',所以你可能會覆蓋內存中的一些隨機3字節, 。 – 2012-01-01 22:01:29

+0

'sizeof(char)'總是1(6.5.3.4,§3)。 – 2012-01-01 22:04:41

回答

8

僅僅因爲你正在寫未分配的內存並不意味着程序會崩潰。沒有像那樣的運行時間邊界檢查。由硬件檢測到時要訪問存儲器出通過操作系統分配的地址範圍將發生

的段錯誤。你可能會在堆之前獲得大量的內存訪問權限。

4

malloc實現可以,而且往往會分配多一點內存比你所要求的。大多數實現將最小化爲8或16個字節的最接近倍數。

6

寫入太小的緩衝區是未定義的行爲。沒有保證它會崩潰。它可能不會崩潰。它可能似乎工作。它也可能會悄悄地破壞一些數據。這可能會導致程序做一些意想不到的事情 - 當攻擊者將未定義行爲的影響轉化爲不希望的事情時,會出現很多安全漏洞。通過嚴格閱讀標準,這甚至可能會從你的鼻子召喚惡魔。

在架構層面,通常分配四捨五入到2的某次冪(但不以任何方式保證!),因此爲什麼你沒有看到任何明顯的不良這裏。但不依賴於此,因爲它可以並且確實有所不同。

1

這工作意外。你的malloc可能會分配一個大於單個字符的塊(通常是因爲跟蹤納米片不值得花費)。所以你很可能在你應該擁有的空間之外跑來跑去,但是在你的實現中並不重要。

你的程序仍然是錯誤的,我認爲,根據標準。而且,如果它更大,並且你在無意中發生意外的地方犯了這個錯誤,你會得到各種不良行爲,有時是非法的內存訪問,但有時候只是完全瘋狂的行爲,因爲你可能會損壞你的或系統數據結構。

我們CheckPointer測試工具應該能夠發現這個錯誤;從技術上講,您要存儲在您請求的區域之外,並且可以通過足夠的努力進行檢測。

2

硬件的內存管理器控制完整的內存頁,往往4K。除非寫入溢出頁邊界,否則內存管理硬件不會生成SEGFAULT/Access Violation中斷。

你的例子'工作',因爲'未定義行爲'的大集合中的一個元素'看起來工作正常,至少現在'。如果你的應用程序增加了複雜性,該集的其他成員將出現...