2012-04-14 36 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 2012-04-14 02:41:14

+0

你能舉一個「大數字」的例子嗎? – Beta 2012-04-14 02:43:35

+0

有沒有可以通過命令行傳遞的標誌?或者只是運行「valgrind --leak-check = full 」 – 2012-04-14 02:43:46

回答

3

你儲備的使用不正確。

m_RowVector.reserve(size); 

這裏m_RowVector已預留空間,使載體可以在不重新分配增長。 但是m_RowVector的大小仍然是0,因此訪問任何元素仍然是未定義的。您必須使用resize()push_back()來更改數組的大小,以將元素放入矢量中。

我看不出任何錯誤,但我相信你有其他索引超出了矢量問題的結束。我會將operator []的使用更改爲()中的方法,當您訪問vector的末尾元素併爲錯誤的實際位置提供線索時,會引發異常。

+0

你的建議解決了這個問題,並使用at()是一個很好的觀點。一旦我修復了錯誤,我將在更新中重新發布代碼。 – 2012-04-14 03:02:01