我给出的代码是原程序的问题部分。它随机交换myArray的两个元素N次和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中调用Nth位置会造成问题。
但以下两种方法都不一致地生成随机整数。
save1 = int( (N-1)*rand()/RAND_MAX );nor
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来实现最佳性能。
发布于 2017-07-02 14:27:47
让我们考虑这一行(编辑的qustion):
save1 = int( (N-1)*rand()/RAND_MAX );其中save1是int类型的变量,N是相同类型的const,rand()返回0范围内的int,RAND_MAX。
在C++中,这个表达式是从左到右计算的,所以首先是乘法,然后是除法。如果rand()返回的值大于INT_MAX /(N-1),则此操作会溢出,导致未定义的行为。在大多数实现中,由于两种形式对积分值的补表示,结果可能是负值。
在此之后,执行RAND_MAX整数除法,以便对于任何值x,如-RAND_MAX
您可以看到这里编译和执行您的程序(我只添加了一行以证明我的观点)。请注意有多少次识别码不是零。
在C中,使用rand()生成0到N(排除在外)之间的随机数的一种常见方法是:
int number = rand() % N;
还可以考虑一个更好的算法来洗牌数组,比如费希尔·耶茨,您可以在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);
}发布于 2017-07-02 08:01:20
至少有一件事需要解决:
rand()返回0和RAND_MAX包含的随机整数,因此必须替换
N*rand()/RAND_MAX 通过
N*rand()/(1+RAND_MAX)发布于 2017-07-02 08:22:21
您应该将N替换为(N-1)。也许这就是你想要做的。
save1 = int( (N-1)*rand()/RAND_MAX );
save2 = int( (N-1)*rand()/RAND_MAX );只是想知道您是否打算在语句中使用“Index1”来计算save1和save2。这也会解决问题。
https://stackoverflow.com/questions/44868543
复制相似问题