2012-01-12 4 views
1

私はそれがunsigned long long intでの作業と関係していると推測できます。ランタイムエラー、私の.exeがクラッシュして、なぜ私はわからないのですか

#include <cstdlib> 
#include <iostream> 
#include <cmath> 

using namespace std; 

typedef unsigned long long int uint64; 

int main(int argc, char *argv[]) 
{ 



    uint64 number_in_question = 600851475143LL; 

    long double sqrt_in_question = sqrt(number_in_question); 
    bool primes_array[number_in_question+1]; 



    for (uint64 i = 0; i <= number_in_question; i++) { 
     primes_array[i] = true; 
    } 

    for (uint64 i = 2; i <= sqrt_in_question; i++) { 
     if(primes_array[i] == true) { 
      // for every multiple of this prime, mark it as not prime 
      for (uint64 ii = i*2; ii <= number_in_question; ii += i) { 
       primes_array[ii] = false;   
      } 
     } 
    } 

    for (uint64 i = 0; i <= number_in_question; i++) { 
     if(primes_array[i] == true) 
     cout << i << ", "; 
    } 


    system("PAUSE"); 


    return EXIT_SUCCESS; 
} 

EDIT1: 私がやろうとしています何のいくつかの背景:

私はこのテクニックを模倣しようとしています:http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 私はシンプルを格納するための配列を使用していながら、「それが素数である」1はい、0の場合は0です。最終的な目標はこれを解決することです:

What is the largest prime factor of the number 600851475143 ?ここに掲載されている:http://projecteuler.net/problem=3。私はちょうど素数に取り組んでいますし、素因について作業します。

EDIT2:

私が投稿ウィキペディアのリンクを見ていたら、私は彼らがpuesdocodeが(その上でスキップされ、私が持っているものを思い付いた)とこのノートを持っていたことに気づいてい実現: 大きな範囲が完全に適合しない場合がありますメモリ内にある。これらの場合には、範囲の一部のみが一度にふるい分けされるセグメント化された篩を使用する必要がある。ふるい分けの素数がメモリに保持されないほど大きい範囲については、代わりにソレンソンのような空間効率の良いふるいが使用されます。 したがって、私はこれを "分割篩"法を用いて行う方法を考えなければならないでしょう。

EDIT3:

「問題は」だけアレイメモリのサイズは、将来の参照のためには大きすぎることに焦点を当てているので、[0]の要素を考慮して、配列を変更しました。また、uint64の代わりにboolとして配列を格納しました。

+0

なぜ「unsigned long long int」が原因であると思われますか?デバッガでアプリケーションを実行しましたか?違反行とは何ですか? –

+0

Dev-C++は正しくデバッグできません。しばらくの間、C++で作業していないのですが、コンパイラをダウンロードして(devs-C++)、この問題に取り組んでいます。おそらく私は別のコンパイラを試してみるでしょう。 – ParoX

+0

'uint64 primes_array [number_in_question];' - それは実際にコンパイルされますか? number_in_questionは、定義や列挙ではなく、ランタイム変数です。また、 'uint64 primes_array [] = new uint64 [number_in_question + 1];' – pelya

答えて

5

長さが600851475143uint64の配列を割り当てようとしています。 uint64の8バイトの場合、この配列はメモリのおおよそ4.5TBである600851475143*8byteを占有することになります。あなたのシステムがそれほど多くのメモリを割り当てても(たぶん)、通常はサイズが数MBに制限されているスタックに入れようとしています。さらに、インデックスnumber_in_questionに書き込もうとしていますが、配列の最後のインデックスはnumber_in_question-1です。

+0

4.5TBメモリです。それは理にかなっている。また、流血は決して私に最後のインデックスのものでエラーを与えませんでしたが、私は0番目の要素を持っているので、配列を+ 1として定義する必要があることを理解しています。 – ParoX

3

アレイを作成しようとするとスタックが壊れていると思います。その配列のサイズは非常に大きく、成功するチャンスを得るためにもヒープ上に作成する必要があります。

+0

はい、私は同じ意見を持っています、この配列はスタック上に作成されますが、このサイズのスタックを持つことはできません – rkosegi

+0

ヒープにも問題があります。最近の4TB以上のRAM +スワップはほとんどありません。 –

0

あなたの配列には0からnumber_in_question - 1の番号が付けられた "number_in_question"要素がありますが、配列の大部分が割り当てられる場合でも、forループは利用可能な領域外のprimes_array [number_in_question]にアクセスしようとしますあなたへ。

なぜuint64の配列を割り当てて、各要素に0または1を格納していますか?

編集:また、そのような可変サイズでスタックに配列を割り当てることはできません。そのスペースをヒープ上に割り当てるには、newを使用する必要があります。繰り返しになりますが、あなたのシステムではそれほど多くのスペースを割り当てることができます。

+0

あなたは正しいです、何らかの理由で私はuint64量の要素がuint64型を必要とすると考えましたが、配列はboolとして定義する必要があります。これは編集3で修正されました。 – ParoX

関連する問題