2012-04-14 6 views
0

次のプログラムは、実際に大きな数値(たとえば、600,851,475,143)のすべての素数を計算します。私が大量に入れたときを除いて、デストラクタがアプリケーションをクラッシュさせていることを除いて、すべては今のところ正しく動作します。誰かが私のアプリケーションに間違ったことを見ることができますか? 私の解決策を再確認した後、答えは間違っていますが、質問はまだ有効です。空のデストラクタクラッシュプログラム:C++

#include <iostream> 
#include <iterator> 
#include <algorithm> 
#include <vector> 
#include <cmath> 
#include <stdexcept> 
#include <climits> 

typedef std::vector<unsigned long long>::const_iterator prime_it; 

#define MAX_COL 900000 

struct large_vector 
{ 
public: 
    large_vector(unsigned long long size, unsigned int row) : 
    m_Row(row) 
    { 
    m_RowVector.reserve(size); 
    } 
    std::vector<bool> m_RowVector; 
    unsigned int m_Row; 
}; 

struct prime_factor 
{ 
public: 
    prime_factor(unsigned long long N); 
    ~prime_factor() {} 
    void print_primes(); 
private: 
    std::vector<bool> m_Primes; 
    std::vector<large_vector>m_Vect_Primes; 
    unsigned long long m_N; 
}; 

prime_factor::prime_factor(unsigned long long N) : 
    m_N(N) 
{ 
    // If number is odd then we need the cieling of N/2/MAX_COL 
    int number_of_vectors = (m_N % MAX_COL == 0) ? (m_N/MAX_COL) : ((m_N/MAX_COL) + 1); 
    std::cout << "There will be " << number_of_vectors << " rows"; 
    if (number_of_vectors != 0) { 
    for (int x = 0; x < number_of_vectors; ++x) { 
     m_Vect_Primes.push_back(large_vector(MAX_COL, x)); 
    } 

    m_Vect_Primes[0].m_RowVector[0] = false; 
    m_Vect_Primes[0].m_RowVector[1] = false; 
    unsigned long long increment = 2; 
    unsigned long long index = 0; 
    while (index < m_N) { 
     for (index = 2*increment; index < m_N; index += increment) { 
     unsigned long long row = index/MAX_COL; 
     unsigned long long col = index%MAX_COL; 
     m_Vect_Primes[row].m_RowVector[col] = true; 
     } 
     while (m_Vect_Primes[increment/MAX_COL].m_RowVector[increment%MAX_COL]) { 
     increment++; 
     } 
    } 
    } 
} 

void prime_factor::print_primes() 
{ 
    for (int index = 0; index < m_N; ++index) { 
    if (m_Vect_Primes[index/MAX_COL].m_RowVector[index%MAX_COL] == false) { 
     std::cout << index << " "; 
    } 
    } 
} 

/*! 
* Driver 
*/ 
int main(int argc, char *argv[]) 
{ 
    static const unsigned long long N = 600851475143; 
    prime_factor pf(N); 
    pf.print_primes(); 
} 

更新 私は、これは作業バージョンであるかなり確信している:予備の

#include <iostream> 
#include <iterator> 
#include <algorithm> 
#include <vector> 
#include <cmath> 
#include <stdexcept> 
#include <climits> 

typedef std::vector<unsigned long long>::const_iterator prime_it; 

#define MAX_COL 900000 

struct large_vector 
{ 
public: 
    large_vector(unsigned long long size, unsigned int row) : 
    m_Row(row) 
    { 
    m_RowVector.resize(size); 
    } 
    std::vector<bool> m_RowVector; 
    unsigned int m_Row; 
}; 

struct prime_factor 
{ 
public: 
    prime_factor(unsigned long long N); 
    ~prime_factor() {} 
    void print_primes(); 
private: 
    std::vector<bool> m_Primes; 
    std::vector<large_vector>m_Vect_Primes; 
    unsigned long long m_N; 
}; 

prime_factor::prime_factor(unsigned long long N) : 
    m_N(N) 
{ 
    // If number is odd then we need the cieling of N/2/MAX_COL 
    int number_of_vectors = (m_N % MAX_COL == 0) ? ((m_N/2)/MAX_COL) : (((m_N/2)/MAX_COL) + 1); 
    std::cout << "There will be " << number_of_vectors << " rows"; 
    if (number_of_vectors != 0) { 
    for (int x = 0; x < number_of_vectors; ++x) { 
     m_Vect_Primes.push_back(large_vector(MAX_COL, x)); 
    } 

    m_Vect_Primes[0].m_RowVector[0] = false; 
    m_Vect_Primes[0].m_RowVector[1] = false; 
    unsigned long long increment = 2; 
    unsigned long long index = 0; 
    while (index < m_N) { 
     for (index = 2*increment; index < m_N/2; index += increment) { 
     unsigned long long row = index/MAX_COL; 
     unsigned long long col = index%MAX_COL; 
     m_Vect_Primes[row].m_RowVector[col] = true; 
     } 
     increment += 1; 
     while (m_Vect_Primes[increment/MAX_COL].m_RowVector[increment%MAX_COL]) { 
     increment++; 
     } 
    } 
    } 
} 

void prime_factor::print_primes() 
{ 
    for (unsigned long long index = 0; index < m_N/2; ++index) { 
    if (m_Vect_Primes[index/MAX_COL].m_RowVector[index%MAX_COL] == false) { 
     std::cout << index << " "; 
    } 
    } 
} 

/*! 
* Driver 
*/ 
int main(int argc, char *argv[]) 
{ 
    static const unsigned long long N = 400; 
    prime_factor pf(N); 
    pf.print_primes(); 
} 
+2

[valgrind](http://valgrind.org/)は、あなたを助ける大きな可能性を秘めています。一般に、空のデストラクタクラッシュが発生すると、デストラクタが呼び出される前に他の何かがヒープを破損したことを意味します。 – dasblinkenlight

+0

「大きな数字」の例を挙げることはできますか? – Beta

+0

コマンドラインで渡すフラグはありますか?または、「valgrind --leak-check = full 」 –

答えて

3

あなたの使い方が正しくありません。

m_RowVector.reserve(size); 

ここでm_RowVectorには、再割り当てされずにベクトルが大きくなるように領域が予約されています。 BUTm_RowVectorのサイズはまだ0であるため、どの要素にもアクセスすることは未定義です。要素をベクトルに配置するには、配列のサイズをresize()またはpush_back()に変更する必要があります。

私は何か間違って見えることはできませんが、あなたはベクトルの問題の終わりを超えて他のインデックスを持っていると確信しています。私は演算子[]のメソッドを()のメソッドに変更します。これは、ベクトルの最後の要素にアクセスし、エラーの実際の位置を示すヒントを与えるときに例外をスローします。

+0

を実行してください。あなたの提案はこの問題を修正し、at()を使用するのは良い点です。バグの修正が終わったら、アップデートのコードを再投稿します。 –