创建多个矩阵时出现分段错误(核心转储)

Posted

技术标签:

【中文标题】创建多个矩阵时出现分段错误(核心转储)【英文标题】:Segmentation Fault (core dumped) when creating multiple matrixes 【发布时间】:2018-12-04 15:11:07 【问题描述】:

对于我的计算机视觉课程,我们目前正在研究 Canny 边缘检测算法。对于那些熟悉的人来说,该算法涉及使用图像的灰度来为每个像素创建梯度向量。因此,我的代码有两个矩阵来存储这些信息,一个是幅度,一个是角度。

double edge[height][width];
double max = 0;
for(int r = 0; r<height; r++)

    for(int c = 0; c<width; c++)
    
        if(r==0||c==0||r+1==height||c+1==width)
        
            edge[r][c]=0;
        
        else
        
            edge[r][c]=sqrt(pow((2*greyscale[r-1][c])+greyscale[r-1][c+1]+greyscale[r-1][c-1]-(2*greyscale[r+1][c])-greyscale[r+1][c+1]-greyscale[r+1][c-1],2.0)+pow((2*greyscale[r][c-1])+greyscale[r+1][c-1]+greyscale[r-1][c-1]-(2*greyscale[r][c+1])-greyscale[r-1][c+1]-greyscale[r+1][c+1],2.0));
            if(edge[r][c]>max)
            
                max=edge[r][c];
            
        
    

//cout<<"makes edge"<<endl;
double atans[height][width]; //should work, but creates memory error when uncommented
for(int r = 0; r<height; r++)

    for(int c = 0; c<width; c++)
    
        cout<<r<<", "<<c<<endl;
        if(r==0||c==0||r+1==height||c+1==width)
        
            atans[r][c]=0;
        
        else
        
            atans[r][c] = atan2(2*greyscale[r-1][c]+greyscale[r-1][c+1]+greyscale[r-1][c-1]-2*greyscale[r+1][c]-greyscale[r+1][c+1]-greyscale[r+1][c-1],2*greyscale[r][c-1]+greyscale[r+1][c-1]+greyscale[r-1][c-1]-2*greyscale[r][c+1]-greyscale[r-1][c+1]-greyscale[r+1][c+1]);
        
    

我的代码使边缘矩阵很好,但是当我尝试制作 atan 矩阵时会给我一个分段错误。 有关如何解决此问题的任何建议?

【问题讨论】:

除非heightwidth 是编译时常量,否则这是一个非标准VLA。请记住,堆栈通常在 Linux 上限制为 10MB,在 Windows 上限制为 1MB。 double edge[height][width]; -- 我们需要确切地看到heightwidth 被声明为什么。如前所述,如果 heightwidth 不是常量,则该行不是有效的 C++。 greyscalematrix 的尺寸是多少?应该大于[height][width] OT:考虑使用std::hypot(x, y); 而不是sqrt(pow(x, 2.0) + pow(y, 2.0)); 【参考方案1】:

我假设你定义了greyscale[height][width]

然后,在一行中

atans[r][c] =   
atan2(2*greyscale[r-1][c]+greyscale[r-1][c+1]+greyscale[r-1][c-1]-2*greyscale[r+1][c]-greyscale[r+1][c+1]
-greyscale[r+1][c-1],2*greyscale[r][c-1]+greyscale[r+1][c-1]+greyscale[r-1][c-1]-2*greyscale[r][c+1]
-greyscale[r-1][c+1]-greyscale[r+1][c+1]);

你越界了。

条件:

  r+1==height||c+1==width

还不够。

测试应该是height-1width-1

【讨论】:

@user463035818 谢谢。我修改了我的答案以更准确【参考方案2】:

最可能的问题是对数组的访问越界。有像valgrind 这样的工具可以在不更改代码的情况下检测到这一点。其他可能性包括使用调试器单步执行代码或在对数组的所有访问之前添加asserts。

另一种可能性是从使用普通数组切换到使用 std::vectorstd::vectors 或其他可以轻松支持边界检查的 C++ 集合。

另一种可能性是heightwidth 非常大,因此数组需要访问的内存比您的平台在堆栈上可以访问的内存要多。如果内存不足而不是崩溃,切换到动态分配或可能产生错误的东西将是一个好主意。您也可以先记录它们,看看这是否是一个可能的问题。

我建议不要在堆栈上分配这样的数组,因为不同的平台有不同的堆栈大小限制。因此,即使它确实有效,这也会使您的代码变得脆弱。

【讨论】:

【参考方案3】:

将您的数组分配到一个向量中,最好是一维向量。

问题在于这一行:

double atans[height][width];

如果您使用变量 heightwidth,那么这不是有效的 C++,因为这是 C99。

如果它们是常量,那么它是有效的 C++,但是你在堆栈上分配你的数组并且可能会炸毁它。

【讨论】:

以上是关于创建多个矩阵时出现分段错误(核心转储)的主要内容,如果未能解决你的问题,请参考以下文章

我运行程序时出现“分段错误(核心转储)”

使用 pthread_create 时出现“分段错误(核心转储)”

在opencv c ++中查找图像卷积时出现分段错误(核心转储)错误

尝试声明大数组时出现分段错误和核心转储[重复]

访问共享进程内存时出现分段错误(核心转储)

尝试执行茎文件时出现分段错误(核心转储)