2012-04-14 2 views
0

다음 프로그램은 실제로 많은 수의 모든 소수를 계산합니다 (예 : 600,851,475,143). 지금까지는 소멸자가 응용 프로그램을 크래쉬하는 경우를 제외하고는 모든 것이 올바르게 작동합니다. 누구든지 내 응용 프로그램에 잘못된 것을 볼 수 있습니까? 내 솔루션을 다시 확인한 후에 대답은 잘못되었지만 질문은 여전히 ​​유효합니다. Empty Destructor Crashing 프로그램 : 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()으로 변경해야합니다.

나는 이상한 것을 볼 수는 없지만 다른 문제는 벡터 문제의 끝을 넘어서는 것이라고 확신합니다. 나는 operator []의 메소드를()의 메소드로 바꿀 것입니다. 이것은 벡터 끝의 요소에 접근 할 때 예외를 던질 것이고 오류의 실제 위치에 대한 단서를 줄 것입니다.

+0

제안 사항이 문제를 해결했으며 at()를 사용하는 것이 좋은 지적입니다. 일단 버그 수정을 완료하면 코드를 다시 게시 할 것입니다. –