【问题标题】:Where does this code segfault?此代码段错误在哪里?
【发布时间】:2023-03-19 03:20:01
【问题描述】:

我的问题,现在简化为一个 - 希望是最小的例子,是为什么下面的代码段错误。

如果您找到了后者,当然可以将其视为提议问题的副本。问题是,我在最初的搜索中没有找到问题,很多新手也不知道错误的原因。我建议将此作为我可以找到的副本:

Segmentation Fault before main

但是问题描述很长,所以我相信我的最小化和更短的代码可能更适合说明问题。在任何情况下,它都是重复的。 我建议版主将此设置为副本,并设置从第二个可能的副本到第一个的链接。

#include <stdio.h>


/* Parameters */
#define N 3072  
#define LDA N

/* Main program */
int main()  {
        printf( "-----------------------------------------------> Entry main.\n" );
        /* Local arrays */
    double a[LDA*N];
        printf( "-----------------------------------------------> End main.\n" );
return 0;        
}

时不会发生段错误
#define N 3072

替换为

#define N 5

行时也不会发生段错误

double a[LDA*N];

被省略。

我对没有到达就发生段错误的观察感到特别困惑

printf( "-----------------------------------------------> Entry main.\n" );

我直接放在main的开头。

为了完整起见,我运行如下代码:

ludi@ludi-M17xR4:~/Desktop/tests$ g++ -o minicombo.x minicombo.cc && ./minicombo.x

【问题讨论】:

  • std::ifstream 这是不是 C
  • @Eregrith 确实...谢谢!
  • 如果您想使用输出进行调试,请使用std::cerr(或fprintf(stderr,...,如果必须)。
  • 由于您没有给我们dsyev,我们无法重现错误。如果您准备minimal complete example,错误的原因将变得清晰。首先,如果您认为段错误发生在控制到达main() 的第一行之前,请尝试删除main() 的所有其他行,看看会发生什么。
  • 你会立即出现段错误,因为 double a[LDA*N];main() 中创建了一个 72MB 的数组,这对于自动存储来说太大了。

标签: c++ segmentation-fault lapack


【解决方案1】:

段错误可能是由于数组定义double a[LDA*N];。这将创建一个具有自动存储持续时间(“在堆栈上”)的 72MB 数组。您有多种选择。

  1. 使用以所需大小创建的std::vector&lt;double&gt;resize() 成员函数。
  2. 使用std::unique_ptr&lt;double[]&gt;new[]/delete[] 进行动态分配。请注意,手动内存管理充满危险。
  3. 使数组static 或全局。

【讨论】:

  • 我认为教初学者new[]delete[] 不是一个好主意。当然不要在 C++ 中使用malloc!另外:Lulz,您个人资料页面中的 gif。 :)
  • @BaummitAugen:很好,我在回答中添加了一些可怕的词。
  • 我认为这个答案是正确的,因为我遵循了 beta 的建议并删除了 main() 中的任何内容。没有段错误。然后我逐行添加,当我添加 double a[LDA*N]; 时程序出现了段错误。我现在应该用一个最小的例子重写这个问题吗?
  • @BaummitAugen:你已经说服了我,做出了改变,你的罐头鸡已经在邮件中了。
  • @Ludi:我的猜测是,当进入函数范围时,会为局部变量(包括那些数组)留出空间。我不相信该语言需要在数组存在之前执行printf,即使函数调用出现在数组定义之前。当然,段错误也可能阻止任何缓冲输出出现,这是一个灾难性事件。