2016-04-19 31 views
-2

這爲什麼會這樣工作?關於malloc的奇怪行爲()

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

int main() 
{ 

    char * abc = malloc(1) + 4; //WRONG use of malloc. 
    char * xyz = "abc"; 
    strcpy(abc, xyz); //Should fail. 
    printf("%s\n", abc); //Prints abc 
} 

我期望strcpy失敗,因爲沒有足夠的內存,因爲我將1傳遞給malloc()的參數。相反,它編譯和運行完美無缺(在Linux上的GCC和Windows上的dev C++)。

這是預期的行爲,還是巧合?

我認爲這不是好的做法,但它爲什麼起作用?

如果在malloc()末尾沒有+4,我會得到分段錯誤。這大部分是我很好奇的。

+2

這不是「工作」的意思。 –

+0

你能否詳細說明一下? – ale10ander

+4

調用未定義的行爲總是一個壞主意。研究爲什麼代碼一旦被調用時就沒有用處。不知道爲什麼你懷疑沒有足夠的內存來分配1個字節,但你可能對'malloc'和朋友有一些誤解。而'void *'上的算術也沒有定義。 – Olaf

回答

5

這基本上是一個事實,即在C指針低級別和另一個示範(典型地)未登記。你說你期望它「沒有足夠的記憶力」,但想一想:你期望失敗的是什麼? strcpy功能確實無法檢查是否有足夠空間存儲正在複製的字符串。它無法這樣做;它所得到的只是一個指針。它只是開始複製字符,並且在實踐中它要麼成功就是要死於分段違規。 (但問題是不是死於「內存不足」。)

6

這是undefined behavior不要這樣做!

您正嘗試訪問超出分配區域的內存位置。所以,內存位置是無效和訪問無效內存調用UB。

FWIW,

  • 有在C標準指出的是停止您訪問出界(無效)存儲器和

  • 既不確實strcpy()檢查針對目標的大小緩衝區相對於源長度

所以,這段代碼(以某種方式)編譯。只要你運行它,它擊中UB,什麼都不保證了。

P.S - the only guaranteed thing here is undefined behavior.

+0

查看[this](http://stackoverflow.com/a/25636788/841108)關於* undefined行爲可能發生的情況* –

+0

@BasileStarynkevitch感謝您的鏈接,嵌入到我的答案中。 :) –

1

不要依賴那種行爲。回答者「有力地迴應」是合理的,因爲依賴這種行爲可能潛伏多年,然後有一天,對運行系統的微小調整突然造成災難性的失敗。

它看起來很有效,因爲自從32位計算機出現以來,許多CPU運行庫實現了malloc/free,它們以16字節粒度管理堆。也就是說,使用從1到16的參數調用malloc()可提供相同的分配。所以你會獲得比你所要求的更多的內存,並允許它執行。

valgrind這樣的工具肯定會檢測到問題。