简单的 C++ 会出现间歇性分段错误;程序
我目前正在学习《Thinking in 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) = ?
I'm currently working through Thinking in C++, and chapter 9, exercise 15 gives instructions to time the difference between inline and non-inline constructors. In doing so, I created a metric shedload of object instances in an array, but when I get up to a certain point, the program begins segfaulting intermittently. I'm not doing anything peculiar, and the number doesn't seem to be magical (close to a power of 2 or anything), so it strikes me as very strange. Indeed, the objects are all very small, containing a single integer.
I'm not using any custom compilation or optimization options, and using standard g++
(not icc
or anything).
I'm stumped as heck by this, in what should be a straightforward program. Any insight would be appreciated, as even the strace output (below) doesn't give me any hints.
Thank you in advance.
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();
}
Run log:
$ ./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
The strace output shows it dying here:
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7
f93000
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
And from a successful run:
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) = ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果 sizeof(B) 为 4 字节,则该数组 (b) 的大小为 8374200 字节。这非常接近我猜测的默认最大线程堆栈大小 8 MiB(8388608 字节)。所以看起来你的堆栈溢出了。
If sizeof(B) is 4 bytes, that puts the size of that array (b) at 8374200 bytes. That's pretty close to what I'm guessing is your default maximum thread stack size of 8 MiB (8388608 bytes). So it looks like you're overflowing your stack.
在堆栈上分配 2093550 个
B
对象的数组很可能会导致堆栈溢出。使用new
动态分配它以避免分段错误。Allocating an array of 2093550
B
objects on the stack most probably causes a stack overflow. Dynamically allocate it withnew
to avoid the segmentation fault.