2013-03-27 130 views
0

出於某種原因,當我運行此代碼時,當for循環中的i的值爲7654319時,出現seg故障。但奇怪的是,當我沒有檢查if該值是泛數字,它在沒有段錯誤的情況下正常工作。當我檢查它是否僅僅是pandigital時它也有效;但不適用於兩者。我用gdb單步執行代碼,這裏是輸出我得到:不知道哪裏出現seg故障

Program received signal SIGSEGV, Segmentation fault. 
0x00000000004007d3 in main() at Pand.cc:81 
81  if (isPandigital(i) && Primes[i]) 
6: Primes[i] = <error: Cannot access memory at address 0x7ffefffffff4> 
5: i = <error: Cannot access memory at address 0x7ffefffffff4> 
4: Primes[7654317] = <error: Cannot access memory at address 0x7ffefffffff8> 
3: Primes[7654321] = <error: Cannot access memory at address 0x7ffefffffff8> 
2: Primes[7654319] = <error: Cannot access memory at address 0x7ffefffffff8> 
1: Primes = <error: Cannot access memory at address 0x7ffefffffff8> 

從輸出,似乎由isPandigital(int)功能操縱我的價值,這也影響到主我的價值。這對我沒有任何意義,但是我繼續使用另一個變量來表示isPandigital(int)函數中的i,但我仍然得到相同的錯誤。

有人可以幫我嗎?這些錯誤非常令人討厭,因爲一切似乎都應該起作用,但事實並非如此,解決方案只是隱藏在實施層之下。任何幫助表示讚賞!

#include <cstdio> 
#define MAX 7700000 

typedef unsigned int uint; 

bool* GetPrimes() 
{ 
    const int Need = MAX; 
    bool* Sieve = new bool[Need]; 

    for (int s = 0; s < Need; ++s) 
    Sieve[s] = 1; 

    bool Done = false; 
    uint w = 3; 

    while (!Done) 
    { 
    for (uint q = 3, Prod = w * q; Prod < (uint)Need ; q += 2, Prod = w * q) 
     Sieve[Prod] = false; 

    Done = (w > (Need >> 1) ? true : false); 

    w+=2; 
    } 
    return Sieve; 
} 

bool isPandigital(int num) 
{ 
    int arr [] = {1,2,3,4,5,6,7}, G, count = 7; 
    do 
    { 
    G = num%10; 
    if (arr[G-1]) 
     --count; 
    arr[G-1] = 0; 
    } while (num/=10); 

    return (!count); 
} 

int main() 
{ 
    bool* Prime = GetPrimes(); 
    int i; 

    for (i = 7654321 ;i > 2; i-=2) 
    { 
    if (Prime[i] && isPandigital(i)) 
     break; 
    } 

    printf("%d\n", i); 

    return 0; 
} 
+3

你有沒有考慮調試? – Rapptz 2013-03-27 04:09:35

+0

儘管它與你的段錯無關,但你應該注意到,在完成它之後你不會釋放內存。 – 2013-03-27 04:18:00

+0

另外,你是否有任何機會在http://projecteuler.net/problem=41上工作? :) – 2013-03-27 04:18:29

回答

3

在您的isPandigital函數中。請注意,如果num是10的倍數或與89 mod 10一致,則會出現一些問題。超出範圍的數組訪問通常會導致段錯誤。

發生這種情況的第一個主要是19(或7654319如果從7654321倒退):

bool isPandigital(int num)//num is (76543)19 
{ 
    int arr [] = {1,2,3,4,5,6,7}, G, count = 7; 
    do 
    { 
    G = num%10;  //G is 9 
    if (arr[G-1])  //G-1 is 8; G is only indexed from 0 to 6. 
     --count;    
    arr[G-1] = 0;  //G-1 is 8; G is only indexed from 0 to 6. 
    } while (num/=10); 

    return (!count); 
} 

注意的是,儘管解決方案不會有一個8或9的,任何素你測試可能。

+0

'G = num%10;''num = 19'實際上是'9'。 – Shoe 2013-03-27 04:18:06

+1

謝謝 - 那真是愚蠢。 – 2013-03-27 04:18:59

+0

OMG哥們,你是傳奇!我會盡快修復這個問題! – smac89 2013-03-27 04:23:33

1

看:

G = num%10; 
    if (arr[G-1]) 

所以,如果有什麼G爲零?這也會毀掉你的堆棧,使調試變得困難。

表面上看,isPandigital在傳遞數字是泛數字的情況下工作得很好,否則數組綁定在/ overrun下?

+0

在for循環中,它永遠不會是因爲'num'總是奇數。 – Shoe 2013-03-27 04:12:32

+0

那麼,我會在這個假設上做一個檢查/斷言。 – Keith 2013-03-27 04:14:08

+0

它仍然不是段錯誤的原因。 – Shoe 2013-03-27 04:15:05