【问题标题】:What does 'An Access Violation (Segmentation Fault) raised in your program' mean?“程序中出现访问冲突(分段错误)”是什么意思?
【发布时间】:2013-03-28 12:01:53
【问题描述】:

在我从 main() 调用此函数之前,我的 C 程序编译并运行良好

void rearrangeMainDiagonal(int mat[MAX_ORDER][MAX_ORDER], int order)
{
    int i, j, k=0, l=0, n=0;
    int temp[20], odd_temp[20], even_temp[20];

    for(i=0;i<order;i++) 
    {
        for(j=0;j<order;j++)
        {
            temp[k] = mat[i][i];
            k++;
        }
    }

    for(i=0;i<=k;i++)
    {
        if(temp[i]%2==0)
        {
            even_temp[l] = temp[i];
            l++;
        }
        else
        {
            odd_temp[n] = temp[i];
            n++;
        }
    }

    for(j=0;j<=n;j++)
    {
        temp[j] = odd_temp[j];
    }

    for(i=0;i<=l;i++,j++)
    {
        temp[j] = even_temp[i];
    }

    k=0;
    for(i=0;i<order;i++)
    {
        for(j=0;j<order;j++)
        {
            mat[i][i] = temp[k] ;
            k++;
        }
    }
}

当我运行程序时,会弹出一条消息说'程序已停止工作。请关闭程序。当我尝试逐步执行它时,它显示“您的程序中出现访问冲突”并停止。包含行“temp[j] =odd_temp[j];”的“for循环”弹出错误。

【问题讨论】:

  • 天哪,太苛刻了。啊……好多了。
  • 分段错误通常意味着您正在尝试访问数组外部的数组索引,或者您正在尝试访问 NULL 指针或未初始化的数据。
  • 在像 gdb 这样的 调试器 中运行它。这段代码中除了一大堆的数组索引之外什么都没有,所以你可以放心,但可以肯定其中一个超出了它的界限。 在调试器中运行它.
  • 是的,我可以阅读它,因为我必须提交代码的站点确实支持很多缩进。但是我会为你编辑和缩进它。 @jrok
  • for(i=0;i&lt;order;i++){ for(j=0;j&lt;order;j++){ temp[k] = mat[i][i]; k++; }}mat[i][j] 或第二个循环都不是必需的。

标签: c multidimensional-array matrix int


【解决方案1】:

当您的程序尝试访问未分配给该程序的内存时,会发生分段错误。

分段错误的最常见原因(取消引用 NULL 指针除外)是访问超出其边界的数组。

f.ex:

int arr[5];
for (int i=0; i<=5; i++)
    arr[i]=i;

将引发分段错误,因为您访问了不存在的 arr 的第 5 个元素(因此您尝试访问它后面未分配给您的内存。

您的程序中有多个地方可能会发生这种情况。

void rearrangeMainDiagonal(int mat[MAX_ORDER][MAX_ORDER], int order)
{
    int i, j, k=0, l=0, n=0;

您创建了固定大小的数组,但在使用它们时从不检查索引。 如果我所有其他调整都正确,最好使用:

    int temp[MAX_ORDER], odd_temp[MAX_ORDER], even_temp[MAX_ORDER];

并强制订单低于或等于 MAX_ORDER:

    assert(order <= MAX_ORDER);

根据函数名我怀疑这个

    for(i=0;i<order;i++) 
    {
        for(j=0;j<order;j++)
        {
            temp[k] = mat[i][i];
            k++;
        }
    }

要求temp 的大小为order*order

应该更像

    for(i=0;i<order;i++) 
    {
        temp[i] = mat[i][i];
    }

因此将每个元素放在主对角线上一次在 temp 数组中,现在应该只有 order 的大小

在这里你循环 temp 直到 k'th 元素,你没有在上述循环的版本中设置它,因为你在赋值后增加了 k 所以你应该循环直到k-1 所以使用i&lt;k 而不是i&lt;=k;

    for(i=0;i<=k;i++)

应该变成(在上面的循环改变之后);

    for(i=0;i<order;i++)
    {
        if(temp[i]%2==0)
        {
            even_temp[l] = temp[i];
            l++;
        }
        else
        {
            odd_temp[n] = temp[i];
            n++;
        }
    }

同样,odd_temp 的第 n'th 元素未设置,请使用 j&lt;n

    for(j=0;j<n;j++)
    {
        temp[j] = odd_temp[j];
    }

同样,even_temp 的第 l'th 元素未设置,请使用 i&lt;l

    for(i=0;i<l;i++,j++)
    {
        temp[j] = even_temp[i];
    }

这里发生了与第一个循环相同的错误。 这应该变成:

    for(i=0;i<order;i++)
    {
        mat[i][i] = temp[i];
    }
}

现在您还可以删除变量 k,因为它未使用,如果该函数仍然执行您希望它执行的操作,它应该能够处理顺序为 MAX_ORDER 的矩阵

【讨论】:

    猜你喜欢
    • 2011-06-02
    • 2013-04-10
    • 1970-01-01
    • 2016-11-11
    • 2023-02-22
    • 1970-01-01
    • 2019-11-20
    • 2020-10-28
    相关资源
    最近更新 更多