为啥我的代码会出现分段/核心转储错误?

Posted

技术标签:

【中文标题】为啥我的代码会出现分段/核心转储错误?【英文标题】:Why is my code giving me a segmentation/core dump error?为什么我的代码会出现分段/核心转储错误? 【发布时间】:2019-12-03 18:46:02 【问题描述】:

代码应该是转置一个矩阵:

#include <iostream>
#include <string>
#include <cmath>
#include <stdio.h>
using namespace std;

void transpose(int (&matrix)[3][3] )
    int t[3][3];
    int rows = 3, columns = 3;
    for(int i = 0; i < rows; i++)
        for(int ii = 0; ii < columns; ii++)
            t[ii][i] = matrix[i][ii];
        
    
    for(int i = 0; i < rows; i++)
        for(int ii = 0; ii < columns; ii++)
            matrix[i][ii] = t[i][ii];
        
    


int main()
    int m[3][3] =  
                  1,2,3,
                  4,5,6,
                  7,8,9 
                ;
    int i = 0, ii = 0;
    int rows = 3;
    int cols = 3;
    for(i = 0; i < rows; i ++)
        for(ii = 0; ii < cols; i++)
            cout << m[i][ii] << " ";
        
        cout << "\n";
    
    transpose(m);
    cout << "\n" << endl;
    for(i = 0; i < rows; i ++)
        for(ii = 0; ii < cols; i++)
            cout << m[i][ii] << " ";
        
        cout << "\n";
    
    return 0;

我尝试返回一个数组,使用可变大小的数组,使用不同的语法,甚至更改数组本身而不是使用第二个数组。即使它确实工作了片刻,转置功能也无法正常工作。现在它给出了分段错误/核心转储消息。

【问题讨论】:

不相关:我尝试返回一个数组 数组是 1970 年代问题的优雅解决方案。您永远不想通过值传递数组,因为复制花费了太长时间并且重复占用了太多内存,因此数组衰减为指针并且总是通过引用传递(除非您将数组包装在结构中)。它们也是通过引用返回的,这意味着局部变量数组在函数结束时超出范围,调用者会得到一个指向无效内存的指针。 无关:我认为您可以通过交换值而不是旋转到 temp 并将 temp 复制回来来节省大量工作。 @C12 这个问题仍在未回答的问题列表中。我提供的答案没有解决吗? 【参考方案1】:

你索引m越界:

    for(i = 0; i < rows; i ++)
        for(ii = 0; ii < cols; i++)    // note that you increase i, not ii, here
            cout << m[i][ii] << " ";
        
        cout << "\n";
    

您在main() 的两个内部循环中都犯了同样的错误。解决方案是将内部循环更改为:

        for(ii = 0; ii < cols; ii++)   // increase ii instead
            cout << m[i][ii] << " ";
        

【讨论】:

... 或使用 j 来避免区分 i ("eye") 和 ii ("eye-eye ")! @PiCTo 将变量命名为有意义的名称将有助于避免类似的错误。在这种情况下,我建议yx 当然但是,虽然不是文字,ijk,... 基于它们作为循环变量的典型用法,IMO 仍然有意义。我也相信xy 仍然存在风险,因为没有真正的将(xy)映射到行/列的约定。您可能遇到过m[x][y] 的情况(可能来自数学符号(x, y),其中x 是水平的,y 是垂直的)在矩阵被分配为行数组(通常可视化/绘制为指向水平数组的指针的垂直数组)时使用,因此正确的访问是m[y][x] 因此,基于您的评论,我相信索引矩阵时更好的命名约定是row/col(或r/c)。命名变量是一门艺术,是编写干净代码的基础,不是吗? @PiCTo 如果有人将xy 混淆,反之亦然,我怀疑将它们命名为rowcol 会有所帮助。但是,rowcol 是更好的名称。至少更容易搜索。

以上是关于为啥我的代码会出现分段/核心转储错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的代码结果显示分段错误(核心转储)?

为啥在编译我的代码C(linux)时出现分段错误(核心转储)[关闭]

为啥这个 AT&T 汇编代码会出现分段错误?

在我的模板类示例中,出现“分段错误(核心转储)”错误

为啥我得到分段(核心转储)?

为啥我在 C 中收到警告“分段错误,核心转储”