我给出的代码是原始程序的问题部分。它随机地交换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中调用第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
以获得最佳性能。
答案 0 :(得分:0)
至少要修理一件事:
rand()返回0到RAND_MAX之间的随机整数,因此必须替换
N*rand()/RAND_MAX
通过
N*rand()/(1+RAND_MAX)
答案 1 :(得分:0)
您应该将N
替换为(N-1)
。可能这就是你想要做的事情。
save1 = int( (N-1)*rand()/RAND_MAX );
save2 = int( (N-1)*rand()/RAND_MAX );
只是想知道你的意图是否要使用`Index1&#39;在语句中计算save1&amp; SAVE2。这也将解决问题。
答案 2 :(得分:0)
让我们考虑这一行(已编辑的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&lt; x&lt; RAND_MAX结果为0。
您可以看到here您的程序(我只添加了一行来证明我的观点)编译并执行。请注意indeces不为零的次数。
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);
}