2013-07-26 22 views
-2

使用MinGW 4.6.2(4.7.x似乎並沒有成爲SourceForge上的「最新」,所以這一塊得到了安裝)在這兩個例子中,內存中發生了什麼?

void test(int *in) 
{ 
    *in = 0; 
} 
int main() 
{ 
    int dat; 
    test(dat); 
    return dat; 
} 

正如你可能知道這會給在C項目的警告。

dirpath\fileName.c|8|warning: passing argument 1 of 'test' makes pointer from integer without a cast [enabled by default]

而且2個錯誤的C++項目。

dirpath\fileName.cpp|8|error: invalid conversion from 'int' to 'int*' [-fpermissive]|

dirpath\fileName.cpp|1|error: initializing argument 1 of 'void test(int*)' [-fpermissive]|

我的問題是,是什麼在以下兩種情況下到底會發生(在內存中),假設-fpermissive啓用或編譯的C程序。

  1. dat未初始化並且程序繼續進行(並且沒有發生分段錯誤)。
  2. dat初始化爲42,並且程序繼續進行(並確實發生分段錯誤)。

爲什麼離開dat初始化導致了沒有賽格故障(也許是偶然?),而情況2導致賽格故障(可能是試圖將一個值賦給一個內存位置)?

好奇心f代表什麼-fpermissive,旗或許? (似乎是多餘的)

+0

如果這個問題有什麼問題,請留下我對它如何改進的評論。謝謝。 – Leonardo

回答

3

該方案已未定義行爲,是,所以這是沒有意義的嘗試因其行爲,但無論如何...

test()功能需要一個指向int。該指針將被取消引用並用於設置它指向的int。然而,你不會傳遞給它一個指向int的指針,而是一個未初始化的int--所以它會嘗試將該變量中的任何垃圾值解釋爲內存地址,然後訪問它後面的對象 - 並繁榮。

如果你想正確地調用該函數,你需要寫

test(&dat); 

代替。

f代表-fpermissive,旗可能是什麼?

不,據我所知,它代表「功能」。 (但在-fpermissive的情況下,我會說這代表着「你的代碼是˚F,如果你使用這個標誌..ked」 ...)

+0

當函數調用發生時,它是否有效地執行'in = &dat;'?如果是這樣,'* in = 0;'對計算機意味着什麼? – Leonardo

+0

有時候,其他軟件使用'-fpermissive'應該對他們持懷疑態度,還是他們很受歡迎,認爲他們勝任? – Leonardo

+0

@Leonardo如果你將'dat'傳遞給函數,而不是'&dat',那麼否,它不會。函數調用並不神奇 - 如果你傳遞一個int,那麼它將使用該int的**值**(而不是地址!),並試圖將其解釋爲一個指針。當然這沒有意義,也是錯誤的。 – 2013-07-26 04:49:54

2

至於警告說passing argument 1 of 'test' makes pointer from integer,你想從通過integer的值的地址獲取某些東西。它可能是任何東西。

,當你路過值42,編譯器是越來越被迫取地址42一些值不爲用戶保留,你得到Segfault.By默認的編譯器被分配一定的價值,後來這個值變得地址,不知何故,你很幸運,你沒有得到這個段故障。

+0

我明白了,這似乎已經在我的現場造成了混亂,但我只是想通過閱讀H2CO3的帖子。謝謝! – Leonardo

1

默認爲c 通過值發生。

void test(int *in) 
{ 
    *in = 0; 
} 

test(dat); // passing value 

這裏你傳遞的是未初始化的dat。它會考慮一個垃圾值。所以你試圖使garabage值作爲測試函數中的內存地址。這是未定義的行爲。相反,你可以試試這個。

test(&data); 

來到你的問題。

Q. dat is uninitialized and the program proceeds (and no segmentation fault occurs). 
A. This is an undefined behaviour because your are passing a garbage value. If your 
    garbage value is a proper memory address then it will not cause segmentation error. 
    If it is not proper, it will cause segmentaion error. So it happend at runtime 
    dynamically and can give either segmentation fault or can run. 

Q. dat is initialized to 42, and the program proceeds (and does seg-fault) 
A. Here you have initialized dat to 42. By default c works on pass by value definition. 
    So you are passing 42 to test. test will consider 42 as a memory location, which 
    is not a proper memory location so it cause segmentation error. 
相關問題