массивы — Почему я не могу использовать этот код в C ++?

#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 # работает просто отлично.

-2

Решение

В вашем 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 #. Всегда следует избегать доступа к массивам, так как это может привести к неопределенному поведению (может или не может привести к сбою).

0

Другие решения

Как сказал jpo38:

Совет: Поскольку n становится отрицательным, возможно, оно достигло максимального значения int … используйте отладчик, чтобы проверить это, просто сделайте, перед вашим циклом while:

Это была моя проблема, затем я изменил «int n» на «long long n», потому что «long n» был еще маленьким, и теперь он дает мне правильный ответ. Спасибо всем 🙂 Так легко, но иногда это мелочи, которые вы не видите.

1

После запуска и отладки программы:

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

n кажется 0x93f20374i являющийся 113383) который является отрицательным -1812855948или будет положительным 2482111348 — но переполняет, чтобы стать -1812855948,

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

Цикл заканчивается отрицательным n, вызывая cache[n] врезаться

1