【问题标题】:Increment working very strangely增量工作非常奇怪
【发布时间】:2013-04-03 06:04:52
【问题描述】:

这个程序应该给出任何大小的阶乘的最后 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;
    }
}

【问题讨论】:

  • 你的问题是什么?
  • 抱歉,为什么 counter2 = 1512?为什么会莫名其妙地增加?
  • 没有其他输出,跟别人说的内存有关。
  • 你的平台/编译器是什么?使用Win7+MinGw,我得到的输出是2到100
  • 还有win7+mingw,够奇葩的

标签: c++ increment


【解决方案1】:

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

        numbers[i+1] += counter;

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

从技术上讲,这是undefined behaviour。在实践中发生的情况是您覆盖了 count2 变量,该变量恰好位于数组之后的内存中。

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

【讨论】:

  • 为什么会影响 counter2?
  • @Seb counter2 很可能与内存中的数组相邻,因此数组外的写入可能会写入counter2
  • @Seb:Undefined Behavior 的难点在于 undefined 的意思是 undefined。完全出乎意料的事情可能会发生。所以正确的问题是:为什么它不影响counter2 因为规范说任何事情都可能发生......
  • @Seb:内存错误是这样的。他们可以以看似奇怪的方式表现自己。通常,症状与实际问题完全脱节。
  • @ShivanRaptor:简单:不要写超过分配内存的末尾。
【解决方案2】:

在这一行

 numbers[i+1] += counter;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    相关资源
    最近更新 更多