只是因爲你可以對某些任意地址執行指針算術並不意味着你應該。 C給你很大的靈活性去做你想做的事,但這也意味着它相信你做正確的事情,你不是。
你試圖做的是寫入一個內存地址sizeof(int)
字節超過地址a
。該內存地址不是a
的一部分,寫入它將調用undefined behavior。
至於你的具體情況發生了什麼,局部變量通常存儲在大多數託管實現的堆棧中。所以如果你寫過一個變量的邊界,你很可能會覆蓋相鄰變量或函數的返回地址。鑑於你的程序崩潰了,你可能正在做後者。
這裏的覆蓋另一個變量的說明:
#include <stdio.h>
int main(void)
{
int before = 0;
int a = 1;
int after = 0;
int * arr1 = &a;
*(arr1 + 1) = 2;
printf("%d %d\n", *arr1, *(arr1+1));
printf("before=%d, after=%d\n", before, after);
}
在這個例子中,我把你的例子,之前和之後a
加入一個變量。當我運行它,我得到以下的輸出:
1 2
before=2, after=0
你可以看到,before
現在設置爲2,即使它沒有明確設置。這意味着它出現在a
之後的堆棧中。所以通過編寫一個過去的a
,你最終會寫入before
。
重申,這是未定義的行爲。編譯器可以按任意順序排列堆棧上的變量。例如,如果您要添加額外的printf
調用或使用不同的優化設置進行編譯,您可能會得到不同的結果。我用-O1
重新編譯了上面的代碼,並運行它導致了核心轉儲。
因此,如果需要特定數量的內存,並且沒有明確預留空間,則需要撥打malloc
以獲取所需的內存。然後你可以自由地讀取和寫入該塊。
這是未定義的行爲。 – BLUEPIXY
雖然技術上*未定義的行爲*,但最可能的是您正在寫入不屬於您的堆棧內存。這可能表現爲另一個本地變量或函數參數獲取更改的值。或者你因爲函數的返回地址被破壞 - 或者更糟 - 當函數返回時在指令指針的其他位置結束而崩潰。 – selbie
你需要更多的基本概念研究。你的頭銜反映了根本的誤解。使用'malloc'進行堆分配預留存儲空間供程序使用。您的程序可以使用指針算術來讀取和寫入已經保留的存儲中的值。得到一本好書。 – Gene