私の与えられたコードは、元のプログラムの問題部分です。 myArrayの2つの要素をランダムにN回とT回のループで交換します。プログラムは想定していることをしますが、 "return 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;
}
EDIT: Iは0から(N-1)へのランダムな整数を生成しなければなりませんでした。 myArrayのN番目の場所を呼び出すと問題が発生していました。
しかし、以下のいずれの方法も、ランダムな整数を均一に生成しません。
save1 = int((N-1)*rand()/RAND_MAX);
も
save1 = int(N*rand()/(RAND_MAX+1));
素敵videoは、この方法の問題です。 MicとBob__が指摘しているように、(N-1)*rand()
によって引き起こされたオーバーランの問題もあります。
このモジュロ方法は、広範囲のランダム整数に対しても非常に非効率的です(詳細はarticleを参照)。だから、均一な乱数を生成する私の最高のチャンスは、次の方法です(記事から借りています)。
while(true)
{
int value = rand();
if (value < RAND_MAX - RAND_MAX % range)
return value % range;
}
また、配列の要素をシャッフルするために、最適なパフォーマンスのためrandom_shuffle
機能やFisher–Yates shuffle
を使用するのが最適です。修正する
配列の最後を過ぎて書き込むのはバットシグナルです。そして確かに、rand()はあなたが思っていることをしません。このコードは一般的にはかなり間違っていますが、実際にはランダムではありません。google "C++ fisher yates shuffle"をお願いします。 –
'rand()/ RAND_MAX'は0(またはrand()がRAND_MAXを返すときは1)になる*整数*除算を実行します。 –
RAND_MAXが大きいと、N * rand()の計算がオーバーフローして奇妙なインデックス値が得られます。モジュールの算術演算を使用するか、doubleに変換することができます。 rand()の使用方法の例についてはGoogle stdlib rand – Mic