间接分段错误与简单的C ++程序

时间:2011-02-25 02:07:59

标签: c++ segmentation-fault intermittent

我目前正在使用Thinking in C ++,第9章练习15给出了指示内联和非内联构造函数之间差异的时间。在这样做的过程中,我在一个数组中创建了一个对象实例的度量值,但是当我到达某一点时,程序会间歇性地开始进行segfaulting。我没有做任何奇特的事情,这个数字似乎并不神奇(接近2或任何东西的力量),所以它让我觉得非常奇怪。实际上,对象都非常小,包含一个整数。

我没有使用任何自定义编译或优化选项,并且使用标准g++(不是icc或其他任何内容)。

我很难过,这应该是一个简单的计划。任何见解都会受到赞赏,因为即使是strace输出(下面)也没有给我任何提示。

提前谢谢。

ex15.cc:

#include <ctime>
#include <iostream>
using namespace std;

class A
{
    static int max_id;
    int id;
public:
    A() { id = ++max_id; }
};
int A::max_id = 0;

class B
{
    A a;
public:
    B() {}
};

int main()
{
    clock_t c1, c2;
    cout << "Before" << endl;
    c1 = clock();
    B b[2093550];   // intermittent segfault around this range
    c2 = clock();
    cout << "After; time = " << c2 - c1 << " usec." << endl;
    getchar();
}

运行日志:

$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Segmentation fault
$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Segmentation fault
$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Before
After; time = 40000 usec.
$ ./ex15
Segmentation fault

strace输出显示它在这里死亡:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7
f93000
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

从成功的运行开始:

mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7
f4c000
write(1, "Before\n", 7)                 = 7
times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = -1160620642
times({tms_utime=4, tms_stime=0, tms_cutime=0, tms_cstime=0}) = -1160620637
write(1, "After; time = 40000 usec.\n", 26) = 26
fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7
f4b000
read(0, "\n", 1024)                     = 1
munmap(0xb7f4c000, 4096)                = 0
exit_group(0)                           = ?

2 个答案:

答案 0 :(得分:3)

在堆栈上分配2093550 B个对象的数组最有可能导致堆栈溢出。使用new动态分配它以避免分段错误。

答案 1 :(得分:3)

如果sizeof(B)是4个字节,则将该数组(b)的大小设置为8374200字节。这与我猜测的默认最大线程堆栈大小为8 MiB(8388608字节)非常接近。所以看起来你堆满了。