![](/img/trans.png)
[英]Unhandled exception at 0x00363A09, Stack cookie instrumentation code detected a stack-based buffer overrun
[英]Shuffling elements of Array : stack-based buffer overrun error
我給定的代碼是原始程序的問題部分。 它將N次隨機交換myArray的兩個元素,並進行T次循環。 該程序執行了預期的操作,但是在單擊“返回0”后,它顯示錯誤消息“ program.exe已停止工作”。 調試輸出顯示
Stack cookie instrumentation code detected a stack-based buffer overrun
為什么程序在完成工作后顯示錯誤? 我怎樣才能解決這個問題 ?
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
const int N = 10000;
const int T = 100;
srand((unsigned)time(0));
bool myArray[N] ;
bool temp = true;
int save1 = 0;
int save2 = 0;
//initializing myArray
for (int index = 0; index < N/2; index++) {
myArray[index] = false;
}
for (int index = N/2; index < N; index++) {
myArray[index] = true;
}
for (int index = 0; index < T; index++) {
for (int index1 = 0; index1 < N; index1++) {
save1 = int( N*rand()/RAND_MAX );
save2 = int( N*rand()/RAND_MAX );
temp = myArray[save1];
myArray[save1] = myArray[save2] ;
myArray[save2] = temp;
}
}
cout<<" Press any key to exit...";
cin.get();
return 0;
}
編輯:我必須生成從0到(N-1)的隨機整數。 在myArray中調用第N個位置會導致問題。
但是以下兩種方法均不能統一生成隨機整數。
save1 = int( (N-1)*rand()/RAND_MAX );
也不
save1 = int( N*rand()/(RAND_MAX+1) );
關於此方法的問題,有一個很好的視頻 。 正如Mic和Bob__指出的那樣,還有(N-1)*rand()
引起的超限問題。
對於較大范圍的隨機整數,這種取模方法也非常無效(請查看本文以了解詳細信息)。 因此,生成統一隨機數的最佳機會是以下方法(從本文中借用)。
while(true)
{
int value = rand();
if (value < RAND_MAX - RAND_MAX % range)
return value % range;
}
同樣對於混洗數組元素,最好使用random_shuffle
函數或Fisher–Yates shuffle
以獲得最佳性能。
至少要解決的一件事:
rand()返回介於0和RAND_MAX(含)之間的隨機整數,因此您必須替換
N*rand()/RAND_MAX
通過
N*rand()/(1+RAND_MAX)
您應將N
替換為(N-1)
。 大概就是您想要的。
save1 = int( (N-1)*rand()/RAND_MAX );
save2 = int( (N-1)*rand()/RAND_MAX );
只是想知道您是否打算在語句中使用“ Index1”來計算save1和save2。 那也將解決問題。
讓我們考慮一下(已編輯的問題的)這一行:
save1 = int( (N-1)*rand()/RAND_MAX );
其中save1
是int
類型的變量, N
是相同類型的const,而rand()
返回范圍為[0,RAND_MAX]的int
。
在C ++中,此表達式是從左到右求值的,因此首先是乘法,然后是除法。 如果rand()
返回的值大於INT_MAX /(N-1),則此操作溢出,導致未定義行為。 在大多數實現中,由於整數值的二進制補碼表示,結果可能是負值。
之后,執行RAND_MAX的整數除法,以便對於-RAND_MAX <x <RAND_MAX的任何值x,結果均為0。
您可以在此處看到您的程序(我只添加了一行來證明我的觀點)已編譯並執行。 請注意,索引的次數不為零。
在C中,使用rand()
生成介於0和N之間的隨機數(不包括在內)的常見方法是:
int number = rand() % N;
還要考慮一種更好的算法來對數組進行混洗,例如Fisher Yates ,您可以在C語言中實現為:
void my_c_shuffle(bool *arr, size_t n)
{
while ( n > 1 )
{
size_t choice = rand() % n;
--n;
bool temp = arr[n];
arr[n] = arr[choice];
arr[choice] = temp;
}
}
在C ++中,您應該使用標准庫而不是重寫這些算法:
#include <iostream>
#include <random>
#include <array>
#include <algorithm>
int main()
{
std::random_device rd;
std::mt19937 g(rd());
std::array<bool, 10000> my_array;
auto middle = my_array.begin() + my_array.size() / 2;
std::fill(my_array.begin(), middle, false);
std::fill(middle, my_array.end(), true);
std::shuffle(my_array.begin(), my_array.end(), g);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.