13

该程序应该给出任何大小的阶乘的最后 100 位数字。然而,main() 中的 counter2++ 发生了一些奇怪的事情。每次循环在 main() 函数中运行(即 99 次),counter2 都会增加 +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

Counter2 最终是 1512 而不是 100,但是如果我从 main() 中删除 mult(i) 或 carry(),那么它会显示 100。为什么 counter2 最终是 1512 而不是 100?

#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;
    }
}
4

2 回答 2

14

numbers您正在写超出数组末尾的内容carry()

        numbers[i+1] += counter;

在这里,ican be 99,在这种情况下numbers[i+1]超出范围。

从技术上讲,这是未定义的行为。在实践中发生的事情是您覆盖了count2变量,该变量恰好位于数组之后的内存中。

关于内存错误的一件令人讨厌的事情是,它们可以长时间无症状,然后在最坏的情况下浮出水面。valgrind是检测此类问题的好工具。

于 2013-04-11T06:38:08.627 回答
2

在这一行

 numbers[i+1] += counter;

numbers[100];
当您更改位于内存中数字旁边i == 99的值(在您的情况下,但不一定)时,您正在写入超出数组的范围。int counter2 = 0;

于 2013-04-11T06:39:07.950 回答