2016-11-30 105 views
0

我有一个问题。我必须编写一个程序来计算随机生成的数字表(冲突测试)的冲突。例如表[1,2,2,3,4,5,5,5,6]有3次碰撞。for循环崩溃的大数

而我的问题是,每当我尝试增加数字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

10^14比普通整数可以容纳得多。您可能需要一个未签名的__int64。看到整数限制在这里:https://msdn.microsoft.com/en-us/library/296az74e.aspx –

+0

n = 519150是远不及中间限制,它不适合我; <我试图保留它长,加倍,没有一个工作。我也尝试过unsigned,但仍然不适用于更大的n – Sarah

+0

@Sarah停止这样做:'int lwKomorkach [n-1];'这不是标准的C++。使用'std :: vector',如果你的问题消失了,我不会感到惊讶。你正在使用“可变长度数组”,这是非常规的,很可能你正在使用它们吹出堆栈。使用标准的C++,'std :: vector'。 – PaulMcKenzie

回答

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-

+0

我试图更改lwKomorkach [n]但它崩溃 – Sarah

+0

在您的代码没有表[3]。我正在谈论你由lwKomorkach [n-1]定义的数组。 –

+0

它会如何修正?我试图改变它,但没有任何工作 – Sarah

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例外,而不是“崩溃”或更糟的是,没有得到崩溃,并且相信你的程序工作正常时,它真的不工作心病rectly。您应该在您的其他for循环中应用相同的测试。

修复边界问题后,您可以将代码从at()更改为使用[ ],因为边界误差已解决。

的最后一个问题是qsort使用。改为使用std::sort。该std::sort是更容易使用(没有施法所有的地方),可以通过编译器更容易进行优化,并且可以为任何类型的工作(而qsort仅适用于POD或C兼容的类型)。

#include <algorithm> 
//... 
std::sort(lwKomorkach.begin(), lwKomorkach.end()); 
+0

非常感谢!完美的作品! – Sarah