【问题标题】:Unable to resolve this error of "Access violation"无法解决此“访问冲突”错误
【发布时间】:2015-02-06 22:49:35
【问题描述】:

我正在尝试使用 Eratosthenes 筛解决 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 = 100000000n = 110000000 的代码运行良好,但 m = 999899999n = 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;
        }

【问题讨论】:

  • 我认为问题出在这一行k = k + arr[i];
  • calloc() 中,如果n &lt;=1 怎么办?还有,你检查成功了吗?
  • 在调试器下运行你的代码。
  • free 应该进入while 主体,以便它匹配calloc。否则,您将分配 x 次,但只释放一次。
  • 另外,看看 Himanshu 说的:你增加k,然后写信给arr[k],而不检查它是否在范围内。你可能应该先写然后再增加。 for 条件将防止越界访问。 (当然,你必须调整k的初始值。)

标签: c long-integer dynamic-allocation calloc


【解决方案1】:

在此代码块中:

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 时会发生这种情况

【讨论】:

  • 是的。"k = k + arr[i]" 正在创建错误。谢谢你。但我仍然收到大量错误。示例 - 对于 m = 100000000 和 n = 110000000,代码运行良好,但对于 m = 999899999 和 n = 999999999 显示以下错误。错误是 -“spoj1.exe 中 0x778a15ee 处的未处理异常:0xC0000005:访问冲突写入位置 0x00000000。”修改后的代码是 - for(k = arr[i]-2; k
【解决方案2】:

除了已回答的内容外,您的释放也不正确。首先,如果while 循环的迭代不止一次发生(arr 被对 calloc 的新调用覆盖并且永远不会被释放),您可能会发生内存泄漏。此外,如果while 循环发生零次,那么您正在释放一个包含垃圾的指针(因为它从未被初始化)。您必须在 while 循环中调用 free(或保存 arr 的所有值并在最后进行适当的检查)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-27
    • 2016-10-20
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 2013-04-06
    相关资源
    最近更新 更多