C 无法解决此错误";访问违规”;

C 无法解决此错误";访问违规”;,c,long-integer,dynamic-allocation,calloc,C,Long Integer,Dynamic Allocation,Calloc,我正试图用埃拉托什尼筛来解决SPOJ的PRIME1问题。该代码适用于较低的整数,但对于长整数显示以下错误- “spoj1.exe中0x770d15ee处的未处理异常:0xC0000005:访问冲突写入位置0x0014010c。” 请帮我解决这个问题。此外,我是新的编码,所以请容忍我犯的任何错误 这是我的密码- #include <stdio.h> #include <stdlib.h> int main() { int m, n, test, i, k;

我正试图用埃拉托什尼筛来解决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;
}
在此代码块中:

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[]
         }
     }
 }
(i=0;i { 如果(arr[i]!=0) { 对于(k=arr[i]-2;k
循环的内部
可能超出
arr[]
的界限。当
k
大于
n-2

时会发生这种情况。此外,您的释放是不正确的。首先,如果
while
循环的迭代次数超过一次(arr会被对calloc的新调用覆盖,并且永远不会被释放),则可能会出现内存泄漏。另外,如果
while
循环发生零次,则您正在释放一个保存垃圾的指针(因为它从未初始化)。您必须将对
free
的调用放在while循环中(或者保存
arr
的所有值,并在末尾进行适当的检查)。

我认为问题出在这一行
k=k+arr[I]
calloc()
中,如果
n在调试器下运行代码,该怎么办?
free
应该进入
while
主体中,使
calloc
变模糊。否则,您将分配x次,但只释放一次。此外,请查看Himanshu所说的:您增加
k
,然后写入
arr[k]
,而不检查它是否在范围内。你可能应该先写,然后增加。
for
条件将阻止越界访问。(当然,您必须调整
k
的初始值。)是的。“k=k+arr[i]”正在创建错误。非常感谢。但我仍然得到一个错误的大数字。示例-对于m=100000000和n=110000000,代码运行正常,但对于m=99989999和n=999999999,代码显示以下错误。错误为“spoj1.exe中0x778a15ee处的未处理异常:0xC0000005:访问冲突写入位置0x00000000。”修改后的代码为-for(k=arr[i]-2;k
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[]
         }
     }
 }