-2

所以我的错误表明我无权访问此内存。这是它的代码,我正在尝试让 collaz 系列工作。n但即使它不应该,我的也会变得消极。

const int number = 1000000;

//Chain Vars-------------------
int chainLength = 0;
int startingNumber = 0;
int chain = 0;
int n = 0;
//----------------------------

for (int i = 2; i <= 1000000; i++)
{
    n = i;
    chain = 0;

    while (n != 1 && n >= i)
    {
        chain++;
        if ( (n % 2) == 0)
        {
            n = n / 2;
        }
        else
        {
            n = n * 3 + 1;
        }
    }
}
4

3 回答 3

1

在您的for循环中,您执行以下操作:

for (int i = 2; i <= 1000000; i++)
{
    n = i;
    chain = 0;

    while (n != 1 && n >= i)
    {
        chain++;
        if ( (n % 2) == 0)
        {
            n = n / 2;
        }
        else
        {
            n = n * 3 + 1;
        }
    }

    //Store the chain length in cache
    cache[i] = chain + cache[n];
    //-------------------------------

    if (cache[i] > chainLength)
    {
        chainLength = cache[i];
        startingNumber = i;
    }
}

在某些时候while (n != 1 && n >= i),很可能最终n会大于1000000。然后,您将访问cache(当您这样做时cache[n])越界(即[0:1000000])。

在循环std::cout << "i is " << i << std::endl;之前添加。while后添加 std::cout << "n is " << n << std::endl;。运行程序,你会得到(几秒钟后):

...
i is 113381
n is 85036
i is 113382
n is 56691
i is 113383
n is -1812855948
Erreur de segmentation (core dumped)

给你。现在,您可以使用调试器、识别错误、修复错误(很可能重新设计循环)并使其工作!;-)

提示:当n变为负数时,它可能达到了int的最大值......然后只需使用错误类型(如long long int或 uint64_t)。然后,你很可能不会得到任何过低(除非你number犯错误)。

C# 不像 C++ 那样管理内存。如果在此处访问数组越界,您可能不会收到任何错误(或者,如上所述,您很幸运)。我对 C# 不熟悉。必须始终避免访问数组,因为它可能具有不确定的行为(可能或不可能导致崩溃)。

于 2016-01-07T21:54:27.870 回答
1

运行并调试程序后:

    //Store the chain length in cache
    cache[i] = chain + cache[n];

n似乎是0x93f20374(at ibeing 113383) 是消极-1812855948的,或者是积极的2482111348- 但溢出成为-1812855948

while (n != 1 && n >= i)

循环以负结束n,导致cache[n]崩溃。

于 2016-01-07T22:00:18.413 回答
1

就像 jpo38 说的:

提示:随着 n 变为负数,可能它达到了 int 的最大值......使用调试器来验证,只需在 while 循环之前执行:

那是我的问题,然后我将“int n”更改为“long long n”,因为“long n”仍然很小,现在它给了我正确的答案。谢谢大家 :) 很简单,但有时这是你看不到的小事。

于 2016-01-07T22:13:50.817 回答