for循环崩溃大号

时间:2016-11-30 23:43:08

标签: c++ loops for-loop random gsl

我有问题。我必须编写一个程序来计算随机生成数字表的碰撞(碰撞测试)。例如,表[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;
}

2 个答案:

答案 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::sortstd::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