![](/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.