为什么我不能在c ++中使用这段代码?

时间:2016-01-07 21:48:57

标签: c++ arrays caching collatz

#include <iostream>
#include <time.h>

using namespace std;

int main()
{
    const int number = 1000000;

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


    // start Time-----------------
    clock_t startTime = clock();
    double duration;
    //---------------------------


    //Cache-----------------------------
    int* cache = new int[number+1];

    for (int i = 0; i < number+1; i++)
    {
        cache[i] = -1;
    }
    cache[1] = 1;
    //---------------------------------


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


    //-----------------------------------------------------------------------------------------------
    duration = ( (clock() - startTime ) / (double)CLOCKS_PER_SEC );
    cout << "Starting Number is: " << startingNumber << " with a length of: " << chainLength << endl;
    cout << "Duration = " << duration << endl;
    //-----------------------------------------------------------------------------------------------

    getchar();

    return 0;
}

所以我的错误发生在第54行,并说我没有访问此内存的权限。 c#中的相同代码工作正常。

3 个答案:

答案 0 :(得分:1)

运行并调试程序后:

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

n似乎是0x93f20374i113383),这是负-1812855948,或者是2482111348 - 但是溢出成为-1812855948

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

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

答案 1 :(得分:1)

像ppo38一样说:

提示:当n变为负数时,也许它达到了int的最大值...在你的while循环之前使用调试器验证,只需这样做:

这是我的问题,然后我改变了#34; int n&#34;到了#长; n&#34;因为&#34;长n&#34;仍然很小,现在它给了我正确的答案。谢谢大家:)这很简单,但有时它是你看不到的小东西。

答案 2 :(得分:0)

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 bugger。)

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