2014-11-01 29 views
0

所以我有這個數組可以存儲添加兩個數組的結果。該數組的大小是10和要添加的數字的數組的大小也10打印數組是否溢出

我的問題是我想打印"Overflow"如果相加後的數組溢出,如果打印"No change"元素個數在添加之後,排列不會超過10

我試圖實施2種情況:

i。第一是增加「result」數組的大小至11,然後給條件

if (result[11]!=int(32)) 
    cout<<"Overflow"<<endl; 

II。我想用其他的邏輯是:

int count = 0; 
for (int i=0;i<11;++i){ 
    if (result[i]!= int(16)) 
     ++count; 
} 

cout<<count<<endl; 

if (count >10) 
    cout<<"Overflow"<<endl; 

問題是,它是打印count作爲11即使結果由數組中10數字。

我也想使用動態數組,但我是C++的新手,所以不知道這是否是一個好主意。我希望提供一些建議。

+1

那麼,你基本上是試圖增加邊界檢查,基本數組? – 2014-11-01 15:48:15

+0

是的,這將是一種說法。 – 2014-11-01 15:51:00

+1

由於您使用的是C++,因此寧願使用'std :: array'或'std :: vector'。 'at()'成員函數提供了運行時邊界檢查,而'std :: get'提供了編譯時間邊界檢查。否則,請考慮使用靜態分析工具或clang和gcc的'-fsanitize = undefined'。海灣合作委員會也可能通過警告超出界限。 – 2014-11-01 15:52:16

回答

1

問題是,它是印刷的計數爲「11」即使結果 由陣列中的10個號碼。

這是因爲你的循環運行11次,以及增加計數即11次從0到10

for (int i = 0; i < 11; i++) 
+0

計數的增量不是無條件的。 – 2014-11-01 15:53:52

-1

「我的問題是要打印的」溢出「如果添加後數組溢出並且打印」無變化「,如果添加之後數組中元素的數量不超過10個。」

你必須做出界索引檢查之前訪問,或者使用越界檢查代碼注入預先。

+0

您還可以使存儲大於所需的陣列,存儲在未使用的空間金絲雀事前,事後檢查它沒有被破壞。或者使用MPU,就像efence一樣。許多方法來檢測出界限訪問。 – 2014-11-01 15:53:34

2

一兩件事你可以做的是建立一個緩衝區域陣列外搭上額外寫道:

int array[SIZE + 1]; 
array[SIZE] = MAGIC; 

// use array [0... SIZE-1] 

if (array[SIZE] != MAGIC) /* overflowed */ 

然而,儘管這種捕捉溢出到緩衝器區域的大小,如果代碼變過去那種,您有未定義的行爲,並且在UB發生後,您的if測試不能保證能夠正常工作。實際價值寫入的機會也很小,等於MAGIC ......但如果您正確選擇金絲雀值,發生這種情況的機率相當小。

儘管這是一個非常好的超限檢測開始,而且大多數動態分配器在調試編譯時都是這樣做的。

更高級的技術是將陣列放置在內存的無效區域的旁邊,在這種情況下,CPU硬件(準確地說是內存保護單元)將會在內存中生成陷阱(訪問衝突或SIGSEGV)確定出界的準確位置。 efence庫使用這種技術。

+0

是否可以詳細闡述一下? – 2014-11-01 16:00:50

+0

@ nothing:您對哪部分有疑問? – 2014-11-01 16:02:31

+0

我已經將結果數組的大小從'10'增加到了'11',爲什麼需要使用緩衝區? – 2014-11-01 16:06:18

0

問題是,即使結果 包含數組中的10個數字,它也會將計數值打印爲'11'。

如果我正確理解這一點,您將訪問大小爲10的數組的第10個索引,這是未定義的行爲,因爲它超出了邊界訪問範圍。

如果您使用C++ 03,你能避免原陣列的使用和喜歡std::vectorstd::vector自動處理內存,爲您和其at()成員函數,如果你嘗試提供一個出界指數會拋出異常。被警告operator[]不提供邊界檢查。

在C++ 11,可以使用std::array。到std::vector相似,它有at()提供邊界檢查和operator[]哪些沒有。非成員函數std::get提供編譯時邊界檢查。這裏有一個例子:

std::array<int, 5> arr { 1, 2, 3, 4, 5 }; 
std::get<6>(arr); 
// error: static assertion failed: index is out of bounds 
arr.at(6); 
// terminate called after throwing an instance of 'std::out_of_range' 
// what(): array::at: __n (which is 6) >= _Nm (which is 5) 

如果你堅持原始陣列,編譯器可能會與幫助抓出界失誤,如LLVM的不確定行爲消毒(這已經被移植到GCC的診斷或工具)和Valgrind的(所報道的內存錯誤)下面是鏘給人的出界警告的例子:

int arr[5] = { 1, 2, 3, 4, 5 }; 
arr[6]; 
// warning: array index 6 is past the end of the array (which contains 5 elements) [-Warray-bounds] 

和消息,如果你有-fsanitize=address,undefined運行它,您將獲得:

runtime error: index 6 out of bounds for type 'int [5]' 

GCC在一個循環中捕獲未定義行爲:

for (int i = 0; i < 6; ++i) 
    std::cout << arr[i]; 
// warning: iteration 5u invokes undefined behavior [-Waggressive-loop-optimizations] 

這是使用-Wall -Wextra -pedantic,這兩種編譯器的工作奠定了良好的說法,但被警告,你得到確切的診斷各不相同,所以總是測試多代碼工具。