我正在尝试使用Eratosthenes的Sieve来解决SPOJ的PRIME1问题。该代码适用于较低的整数,但对于长整数显示以下错误 -
“spoj1.exe中0x770d15ee处的未处理异常:0xC0000005:访问冲突写入位置0x0014010c。”
请帮我解决一下。我也是编码的新手,所以请承担我所犯的任何错误。
这是我的代码 -
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m, n, test, i, k;
long int *arr, p;
scanf("%d", &test);
while (test--)
{
scanf("%d%d", &m, &n);
arr = (long int *)calloc(n - 1, sizeof(long int));
if (m == 1)
{
m = 2;
}
arr[0] = 2;
for (i = 1; i < n - 1; i++)
{
arr[i] = arr[i - 1] + 1;
// printf("%d\n",arr[i]);
}
for (i = 0; i < n - 1; i++)
{
if (arr[i] != 0)
{
for (k = arr[i] - 2; k < n - 1; )
{
k = k + arr[i];
arr[k] = 0;
}
}
}
for (i = 0; i < n - 1; i++)
{
if (arr[i] != 0 && arr[i] >= m)
{
printf("%d\n", arr[i]);
}
}
printf("\n");
}
free(arr);
return 0;
}
修改
是。 k = k + arr[i]
正在创建错误。谢谢。但是对于大数字我仍然会收到错误。示例 - 代码适用于m = 100000000
和n = 110000000
,但m = 999899999
和n = 999999999
显示以下错误。错误是 - “spoj1.exe中0x778a15ee处的未处理异常:0xC0000005:访问冲突写入位置0x00000000。”修改后的代码是 -
for(k = arr[i]-2; k<n-1;)
{
k = k + arr[i];
if(k < n-1)
{
arr[k] = 0;
}
答案 0 :(得分:0)
在此代码块中:
for (i = 0; i < n - 1; i++)
{
if (arr[i] != 0)
{
for (k = arr[i] - 2; k < n - 1; )
{
k = k + arr[i];
arr[k] = 0; // <-- this line can/will access an element of arr[]
// that is beyond the bounds of the arr[] array
// remembering that arr[] only contains n-1 elements
// therefore the max offset is m-2
// so, when 'k' gets to be >= n-1
// then arr[k] is accessing an element
// beyond the end of arr[]
}
}
}
内部for
循环可能会超出arr[]
的范围。当k
大于n-2
答案 1 :(得分:0)
除了已经回答的内容之外,您的免费还不正确。首先,如果while
循环的迭代发生多次(arr被新的calloc调用覆盖并且永远不会被释放),则可能会出现内存泄漏。此外,如果while
循环发生零次,那么您将释放一个包含垃圾的指针(因为它从未被初始化)。你必须在while循环中调用free
(或者保存arr
的所有值并在结尾处进行适当的检查。)