为啥我的代码会出现分段/核心转储错误?
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 将变量命名为有意义的名称将有助于避免类似的错误。在这种情况下,我建议y
和x
。
当然但是,虽然不是文字,i
,j
,k
,... 基于它们作为循环变量的典型用法,IMO 仍然有意义。我也相信x
和y
仍然存在风险,因为没有真正的将(x
、y
)映射到行/列的约定。您可能遇到过m[x][y]
的情况(可能来自数学符号(x, y),其中x 是水平的,y 是垂直的)在矩阵被分配为行数组(通常可视化/绘制为指向水平数组的指针的垂直数组)时使用,因此正确的访问是m[y][x]
。
因此,基于您的评论,我相信索引矩阵时更好的命名约定是row
/col
(或r
/c
)。命名变量是一门艺术,是编写干净代码的基础,不是吗?
@PiCTo 如果有人将x
与y
混淆,反之亦然,我怀疑将它们命名为row
和col
会有所帮助。但是,row
和 col
是更好的名称。至少更容易搜索。以上是关于为啥我的代码会出现分段/核心转储错误?的主要内容,如果未能解决你的问题,请参考以下文章