Прерывистые ошибки сегментации с простой программой 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
чтобы избежать ошибки сегментации.