Прерывистые ошибки сегментации с простой программой C++

В настоящее время я работаю над Thinking в C++, и в главе 9, упражнение 15 даются инструкции, чтобы определить разницу между встроенными и не встроенными конструкторами. При этом я создал метрическую загрузку экземпляров объектов в массиве, но когда я добираюсь до определенной точки, программа начинает прерывистое сегментирование. Я не делаю ничего особенного, и число не кажется волшебным (близко к степени 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 ответа

Решение

Если sizeof(B) составляет 4 байта, то размер этого массива (b) устанавливается равным 8374200 байтов. Это довольно близко к тому, что я предполагаю, ваш максимальный размер стека потока по умолчанию 8 МБ (8388608 байт). Похоже, вы переполняете свой стек.

Выделение массива 2093550 B объекты в стеке, скорее всего, вызывают переполнение стека. Динамически распределить его new чтобы избежать ошибки сегментации.

Другие вопросы по тегам