为什么这会可变地变为负值?
Why is this variably turning negative?
所以我的错误提示我没有访问此内存的权限。
这是它的代码,我正在尝试让 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;
}
}
}
在你的 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]
)。
在while
循环之前添加std::cout << "i is " << i << std::endl;
。添加
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#。必须始终避免访问数组,因为它可能具有未确定的行为(可能会或不会导致崩溃)。
运行并调试程序后:
//Store the chain length in cache
cache[i] = chain + cache[n];
n
似乎是 0x93f20374
(在 i
处是 113383
),它是负数 -1812855948
,或者是正数 2482111348
- 但溢出成为 -1812855948
.
while (n != 1 && n >= i)
循环以负 n
结束,导致 cache[n]
崩溃。
就像 jpo38 说的:
提示:当 n 变为负数时,可能它达到了 int 的最大值...使用调试器来验证这一点,只需在 while 循环之前执行:
那是我的问题,然后我将 "int n" 更改为 "long long n" 因为 "long n" 仍然很小,现在它给了我正确的答案。谢谢大家 :) 如此简单,但有时是您看不到的小事情。
所以我的错误提示我没有访问此内存的权限。
这是它的代码,我正在尝试让 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;
}
}
}
在你的 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]
)。
在while
循环之前添加std::cout << "i is " << i << std::endl;
。添加
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#。必须始终避免访问数组,因为它可能具有未确定的行为(可能会或不会导致崩溃)。
运行并调试程序后:
//Store the chain length in cache
cache[i] = chain + cache[n];
n
似乎是 0x93f20374
(在 i
处是 113383
),它是负数 -1812855948
,或者是正数 2482111348
- 但溢出成为 -1812855948
.
while (n != 1 && n >= i)
循环以负 n
结束,导致 cache[n]
崩溃。
就像 jpo38 说的:
提示:当 n 变为负数时,可能它达到了 int 的最大值...使用调试器来验证这一点,只需在 while 循环之前执行:
那是我的问题,然后我将 "int n" 更改为 "long long n" 因为 "long n" 仍然很小,现在它给了我正确的答案。谢谢大家 :) 如此简单,但有时是您看不到的小事情。