我有问题。我必须编写一个程序来计算随机生成数字表的碰撞(碰撞测试)。例如,表[1,2,2,3,4,5,5,5,6]有3次碰撞。
我的问题是,每当我尝试将数字n
增加到例如int n = 5191401;
时,我的程序就会崩溃。怎么了?它为什么停止工作?我需要大量的随机数(比如10 ^ 14)。
这是我的代码:
#include <iostream>
#include <gsl/gsl_rng.h>
#include <stdlib.h>
#include<cmath>
using namespace std;
int compare(const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main (void)
{
unsigned int seed=10540000;
gsl_rng * r=gsl_rng_alloc (gsl_rng_minstd);
gsl_rng_set(r,seed);
gsl_rng_env_setup();
int lPrzedzialow=400000000;
int n = 519140;
int z,lKolizji=0;
int lwKomorkach[n-1];
double dlPrzedzialu=1./(lPrzedzialow);
for (int i = 0; i < n; i++)
{
lwKomorkach[i]=floor(gsl_rng_uniform (r)/dlPrzedzialu)+1;
}
qsort (lwKomorkach, n, sizeof(int), compare);
for(z=0;z<=n-1;z++)
{
if(lwKomorkach[z+1]==lwKomorkach[z])
{
lKolizji++;
}
}
cout<<endl<<lKolizji<<endl;
gsl_rng_free (r);
return 0;
}
答案 0 :(得分:3)
你的问题是双重的。
1)您在声明数组时使用非标准C ++语法。
2)访问它时,你很可能会超出数组范围。
要解决第一个问题,这行代码不是标准的C ++。
int lwKomorkach[n-1];
必须使用编译时常量声明C ++中的数组。此外,如果n-1
很大,则存在超过预留堆栈空间量的风险。
缓解此问题的方法是使用std::vector
:
#include <vector>
//...
std::vector<int> lwKomorkach(n-1);
一旦你有了这个,那么为了确保你不会越界,你可以使用std::vector::at()
函数来检查边界:
for (int i = 0; i < n; i++)
{
lwKomorkach.at(i) = floor(gsl_rng_uniform (r)/dlPrzedzialu)+1;
}
如果i
超出范围,您将获得std::out_of_range
异常,而不是“崩溃”或更糟,没有崩溃,并且认为您的程序工作正常工作正常。您应该在其他for
循环中应用相同的测试。
解决边界问题后,您可以将代码从at()
更改为使用[ ]
,因为边界错误已解决。
最后一个问题是qsort
的用法。请改用std::sort
。 std::sort
更容易使用(整个地方没有强制转换),编译器可以更容易地进行优化,并且可以适用于任何类型(而qsort
仅适用于POD或{{1}兼容类型)。
C
答案 1 :(得分:1)
通过那个
int lwKomorkach[n-1];
for (int i = 0; i < n; i++)
{
lwKomorkach[i]=floor(gsl_rng_uniform (r)/dlPrzedzialu)+1;
}
您正在尝试将n个项目放入n-1个大小的数组中。我想它只是偶然地在低位数下崩溃。
在第二次循环中它变得更糟
for(z=0;z<=n-1;z++)
{
if(lwKomorkach[z+1]==lwKomorkach[z]){lKolizji++;}
}
当z = n-1时,你试图分配给lwKomorkach [n],而lwKomorkach的最大索引可以是n-2