2011-08-26 89 views
0
char * s; 
s[400] = 'd'; 

如果不是不確定的行爲,那麼它意味着我不能隨意訪問堆棧超出了我的RAM的任何部分?因此,每次OS啓動一個processus時,它都會分配一個RAM區域,我可以在這裏執行令人討厭的事情(malloc除外),因爲操作系統將在進程完成後清理堆棧。此代碼未定義的行爲?那麼操作系統和堆呢?操作系統如何處理堆棧?

爲什麼不是OS能夠清理堆過程結束之後?這是否意味着堆與其他所有進程共享?

如果我把太多的數據在堆棧中,這是一個緩衝區溢出,但多少我可以把堆棧?是操作系統綁定,內存大小綁定還是CPU緩存綁定?

+1

「未定義的行爲」不意味着你無法訪問它。這意味着如果你這樣做可能會發生任何事情。 –

回答

5

是的,它的行爲是未定義的。

s未初始化,因此s[400]充其量只是內存中的某個不確定位置。

編輯:

最後三個你的問題的段落很少或無關的兩行代碼,我們一直在討論。 s[400] = 'd';的未定義與堆棧,堆,進程或其他任何內容幾乎沒有關係。 s未初始化,因此它包含垃圾;它可能指向記憶中的任何地方,或無處。 s[400]充其量是一個char對象,位於由存儲的垃圾地址指定的未定義位置之外的400個字節爲s

如果你明白,你可能還有問題。我建議發佈一個沒有代碼示例的新問題。

部分回答一些你問:

你的程序可能不合法地試圖訪問,這不是它創建的對象的一部分的任何內存(通過與像char foo[1000];對象定義或通過像char *ptr = malloc(1000);這樣的分配)。在一個特定的實現中,可能是以外的任何聲明對象的一部分內存區域,您可以隨身攜帶,但沒有安全或便攜的方式來執行此操作 - 沒有理由。如果您需要訪問某些內存,請先分配它。

C語言本身甚至不指「堆疊」或「堆」;這些是實現細節。

不,通常不會在進程之間共享堆。通常,當程序結束時,操作系統會整齊地回收所有堆棧分配和堆分配的內存。 (C標準不說這個,因爲它只能勉強維持本身涉及您的程序的執行外面發生了什麼,但它在某些嵌入式系統也許幾乎普遍正確的除外。)

+0

是的,但它不是堆棧... – jokoon

+3

@gokoon:那不是堆棧,可能是任何東西。 BTW,s [400] == *(s + 400) – BlackBear

+0

@gokoon:'s'是一個指針對象。如果你在一個函數中聲明它,它就位於堆棧上(留下一些細節)。與以下語句相關的是's [400] ='d';',是's' *指向的地址*。既然你沒有初始化它,'s'包含垃圾,這意味着'''可以指向內存中的任何地方,或者任何地方(它的內容可能甚至不是有效的指針)。 's [400]'是一個'char'對象,在任何未定義的位置's指向或不指向的地方400字節。試圖修改'[400]'就像你可以得到的那樣未定義。 –

3

是的,這是不確定的行爲,因爲它並不指向的內存爲應用程序分配的塊。

+0

它可以*指向分配的內存塊,只是巧合而已。這對於未定義的行爲如此陰險;它可能會發生像你期望的行爲(不管你的不切實際的期望是什麼)。 –