2013-04-11 10 views
13

このプログラムは、任意のサイズ階乗の最後の100桁を指定します。しかし、main()のcounter2 ++には何か変わったことがあります。 counter2は、ループがmain()関数で実行されるたびに(+199回)、+1されます。しかし、これは表示されているものです。作業が非常に奇妙になった

2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
71 
86 
90 
123 
164 
196 
207 
254 
300 
362 
432 
471 
551 
620 
630 
708 
761 
772 
857 
896 
985 
1036 
1100 
1116 
1207 
1209 
1280 
1356 
1417 
1452 
1512 

カウンタ2は、1512年の代わりに、100されて終わるが、私は(メインから)(MULT(I)のいずれかを削除するか、または運ぶ場合)、それは100なぜカウンタ2が終わるんを表示します100ではなく1512ですか?あなたはcarry()numbers配列の終わりを過ぎて書いている

#include <iostream> 

using namespace std; 

int numbers[100]; 
int counter2 = 0; 

void init(){ 
//sets elements 1-99 of numbers[] to 0, increments counter2 by 1, sets numbers[0] = 1 
    for (int i = 1; i < 100; i++){ 
     numbers[i] = 0; 
    } 
    numbers[0] = 1; 
    counter2++; 
} 

void mult(int x){ 
//multiplies each element by 1 through n to calculate for !n 
//this is used to represent a very large number without using a BigInt library 
//the nth element is a placeholder for the n+1 position of the number 
//e.g 2nd element represents 100-900 of the number, 4th represents 1000-9000, etc 
//carry() is used to take care of overflow, so that it's only 1 digit per element 
    for (int i = 0; i < 100; i++){ 
     numbers[i] *= x; 
    } 
} 

void carry(){ 
//in order to make previous function work, this adds any overflow to the next 
//element. e.g: 8 * 4 = 32, 3 is added to numbers[i+1], sets numbers[i] to 2 
    int counter = 0; 
    for (int i = 0; i < 100; i++){ 
     if (numbers[i] >= 10){ 
      counter = numbers[i]/10; 
      numbers[i+1] += counter; 
      numbers[i] = numbers[i] % (counter * 10); 
     } 
    } 
} 

int main() 
{ 
    init(); 
    for (int i = 2; i < 101; i++){ 
    //calculates the last 100 digits of !100, but counter2 ends up being 1512 
     mult(i); 
     carry(); 
     counter2++; 
     cout << counter2 << endl; 
    } 
} 
+0

あなたの質問は何ですか? – Raptor

+0

申し訳ありませんが、なぜcounter2 = 1512ですか?なぜそれが奇妙に増加していますか? – xyz

+0

他の出力はありません。他の人が言っているように、メモリと関係しています。 – xyz

答えて

14

:ここ

 numbers[i+1] += counter; 

inumbers[i+1]が範囲外である場合には、99することができます。

技術的には、これはundefined behaviourです。実際には、count2変数を上書きすることになります。変数は配列の直後にメモリ内に置かれます。

メモリバグについての1つの厄介なことは、彼らが長期間症状がなくなり、最悪の状況で浮上する可能性があるということです。 valgrindは、このタイプの問題を検出するための優れたツールです。

+0

なぜそれがcounter2に影響しますか? – xyz

+0

'main'から呼び出される' mult 'では、 'i'が100のときにも呼び出されます。 –

+4

@Seb' counter2'はメモリ内の配列にかなり隣接している可能性があるので、配列外の書き込みは 'counter2'と書くことができます。 –

2
このラインで

numbers[i+1] += counter; 

i == 99は、このようにメモリに右隣の数字に座って(あなたのケースでは、必ずしも必要ではないが)int counter2 = 0;の値を変更するときは、アレイnumbers[100];
の境界の外に書いています。

関連する問題