Прерывистые ошибки сегментации с простой программой C ++ - PullRequest
0 голосов
/ 25 февраля 2011

В настоящее время я работаю с 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 ]

3 голосов
/ 25 февраля 2011

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

3 голосов
/ 25 февраля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...