簡體   English   中英

關於在C ++中的訪問沖突?

[英]In regards to access violation in C++?

我必須檢查C ++中不同數據結構中的訪問沖突。 據我所知,這取決於您使用的編譯器。

但是,我想知道為什么當發生訪問沖突時,g ++編譯器傾向於打印一些無意義的數字? 例如,如果我有int a[10]; 並且我做cout << a[100] << endl; ,它將顯示類似49738290的內容,但並不代表任何內容。 它不應該打印null或'\\ 0'之類的東西嗎? 我認為,當迭代器超出范圍時,使用迭代器也會發生相同的情況。

我認為在Visual Studio中,它不會打印類似49738290的內容。它可能會打印null或\\ 0,有時會導致程序崩潰。 這是什么原因呢?

有編譯專家嗎?

“不確定行為”表示結果不確定。 什么都可能發生。 您可以獲得0。 您可以得到一些正數。 您可以得到一些負數。 否則您的程序可能會崩潰。 每次運行該程序時,您都會得到不同的結果。

對於未定義的行為,您無法期望任何特定的結果或動作會發生。

在C ++中,程序在運行時不知道數組的長度(實際上,它可能不知道它是數組還是指針,當傳遞給函數時,兩者都只是作為地址傳遞)。 因此,它假定索引是有效的,並根據數據的大小查看數組的第100個元素。 從技術上講,發生的事情是不確定的-該操作是非法的,因此該應用程序可以執行任何操作。

大多數編譯器/ OS實際發生的情況-它會根據數組的起始位置查看數組中的第100個整數。 根據數組在內存中的位置,它可能是您可以讀取的地址,也可能不是。 如果不是,則會崩潰。 如果是這樣,它將起作用,並且它將讀取那里的任何隨機內存。 可能是其他變量,空格,代碼,從OS分配但尚未使用的內存或其他任何東西。 因此,它是一個偽隨機變量(請勿將其用作隨機數,否則可能會發生不好的事情)。

更有趣的是,如果您嘗試編寫它,除了上面的問題之外,您還可能會覆蓋隨機數據,這可能是其他變量,這些變量將被隨機更改,指針現在將指向其他隨機存儲器,代碼現在,它的功能有所不同,或者是堆棧,在這種情況下,您可以跳轉到隨機內存(實際上,這是某些黑客的工作方式)。

簡而言之,不要超出范圍。

這是什么原因呢?

正如@Sam所說,您正在做的是“未定義的行為”。 那意味着什么都可能發生。 沒事

實際上,將發生的情況是程序將嘗試取消引用未定義值的指針。 我們無法預測會是什么。 這可能取決於執行之前發生的情況。 或不。 C ++語言規范什么也沒說。 (這是“未定義的行為” ...記住。)

指針將是有效地址,或者是不引用有效存儲位置的地址。

  • 如果地址有效,則將獲取該單元格中的值。 我們不知道它將是什么,但是它很可能為零……根據上下文,您將看到它為NULL'\\000' 但這可能是另外一回事。

  • 如果地址無效,則嘗試訪問該地址將產生內存訪問錯誤或分段沖突。 這是由硬件檢測到的,該硬件通常用於實現虛擬內存和/或保護系統免受某個進程(應用程序)訪問屬於OS或另一進程的內存的影響。

這些是典型的現代操作系統中可能發生的行為。 另一方面,如果您的代碼在沒有內存保護的“裸機”系統上運行,則可以想象,您讀取的是一個基本隨機的地址可能會落在內存映射的設備寄存器上,並觸發設備執行以下操作:做一點事。 一切皆有可能。


這個教訓是,當您使用C和C ++進行編碼時,需要仔細編寫代碼,並避免做會導致“未定義行為”的事情。 如果這太難了,請考慮使用一種語言,使編譯器和運行時避免您遇到這種麻煩。 (但這是以性能為代價的。)

正如Sam Varshavchik在回答中所說的那樣,根據C ++標准,行為是不確定的。

這意味着實現(松散地說,編譯器,庫和主機系統的組合)可以產生任何喜歡的結果。 並不需要使用兩個不同的編譯器構建的代碼產生相同的結果。 如果將注意力集中在一個編譯器上,則不能保證今天和下周三將產生相同的結果。

實際上,訪問10元素的數組中的元素100通常會嘗試訪問內存中相應位置的內容。 在您的示例中,如果int為4字節,則訪問a[100]將嘗試將數組開始后400字節開始的四個字節視為int

如果該內存存在(可能不存在,因為它可能在操作系統已分配給您的程序的外部內存中),則所獲得的結果將取決於駐留在內存中該位置的任何內容。 這可能與程序中的其他變量相對應-由程序中的其他代碼將其設置為任意變量。 在運行由操作系統托管的其他程序之后,它可能包含隨機的一組位,這些位對應於該內存中存儲的內容。 操作系統可能會使用一些隨機位覆蓋內存,然后再將其提供給程序使用(是的,出於安全原因,某些操作系統會這樣做)。 如果該內存位置實際上不存在,則訪問它可能會產生某種形式的訪問沖突。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM