0

何らかの理由で、このコードを実行すると、forループのiの値が7654319の場合にセグメンテーション違反が発生します。ただし、奇妙なことに、値がパンデジタルかどうかをチェックしていない場合は、正常に機能します。セグメンテーション違反なし。それが単なるパンデジタルであるかどうかをチェックしているときにも機能します。しかし、両方ではありません。gdbを使用してコードをステップ実行しました。取得した出力は次のとおりです。

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>

出力から、関数のiの値を操作することによりisPandigital(int)、これはmainのiの値にも影響を与えるようです。これは私には意味がありませんでしたが、先に進み、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;
}
4

2 に答える 2

3

あなたのisPandigital関数で。numが10の倍数であるか、8または9mod10と合同である場合、いくつかの問題が発生することに注意してください。範囲外の配列アクセスは、多くの場合、segfaultにつながります。

これが発生する最初の素数は19(または、7654321から逆方向に進む場合は7654319)です。

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は含まれていませんが、テストするプライムには含まれている可能性があることに注意してください。

于 2013-03-27T04:12:30.057 に答える
1

見る:

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

では、Gゼロの場合はどうなるでしょうか。これはスタックを破壊し、デバッグを困難にします。

一見すると、isPandigital渡された数値がパンデジタルの場合にうまく機能します。それ以外の場合、配列はアンダーラン/オーバーランにバインドされていますか?

于 2013-03-27T04:11:11.673 に答える