0

私は現在、C++ での思考に取り組んでおり、第 9 章の演習 15 では、インライン コンストラクターと非インライン コンストラクターの違いを計る方法について説明しています。そうすることで、オブジェクト インスタンスのメトリクス シェッドロードを配列に作成しましたが、特定のポイントに到達すると、プログラムが断続的にセグメンテーション違反を開始します。私は何も変わったことをしていませんし、その数は魔法のようにも見えません (2 のべき乗などに近い) ので、非常に奇妙に思えます。実際、オブジェクトはすべて非常に小さく、単一の整数を含んでいます。

私はカスタム コンパイルや最適化オプションを使用しておらず、標準を使用していますg++(noticcまたは何か)。

単純なプログラムであるはずのこれに、私は困惑しています。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)                           = ?
4

2 に答える 2

3

スタックに 2093550個のBオブジェクトの配列を割り当てると、スタック オーバーフローが発生する可能性が高くなります。newセグメンテーション違反を回避するために動的に割り当てます。

于 2011-02-25T02:11:30.147 に答える
3

sizeof(B) が 4 バイトの場合、その配列 (b) のサイズは 8374200 バイトになります。これは、デフォルトの最大スレッド スタック サイズが 8 MiB (8388608 バイト) であると私が推測しているものにかなり近いものです。そのため、スタックがオーバーフローしているようです。

于 2011-02-25T02:12:30.023 に答える