0

更新 2:コードの後のセクションを参照してください。

GMP ライブラリを使用して PI を計算するためのスレッドを使用していますが、wxThread::OnExit()内部で wxWidgets が呼び出されると、どういうわけかセグメンテーション エラーが発生します。

wxWidgets ソース コードの行は次のとおりです: src/msw/thread.cpp#553

私のスレッドエントリ関数からの短縮コードは次のとおりです。

while (i <= m_numIterations && !TestDestroy()) {
    mpf_div(result, perimeter, edgeCount);

    mpf_pow_ui(result, result, 2);
    mpf_ui_sub(result, 1, result);
    mpf_sqrt(result, result);
    mpf_div_ui(result, result, 2);

    mpf_sub(result, half, result);
    mpf_sqrt(result, result);
    mpf_mul_ui(result, result, 2);
    mpf_mul(result, result, edgeCount);

    mpf_set(perimeter, result);

    i++;
    mpf_mul_ui(edgeCount, edgeCount, 2);
}

// Free GMP variables we don't need anymore
mpf_clear(half);
mpf_clear(result);
mpf_clear(edgeCount);

// OUTPUT_DIGITS has a constant value, e.g. 12
char outputStr[OUTPUT_DIGITS];

mp_exp_t *expptr;

// If commented out, the error does not appear!
mpf_get_str(outputStr, expptr, 10, OUTPUT_DIGITS, perimeter);

更新 2:で最後の行をコメントアウトするとmpf_get_str()、エラーは発生しません。
2003 年からの非常に古いバグ リクエストも見つけました: http://gmplib.org/list-archives/gmp-discuss/2003-November/000888.html

GCC デバッガーからのコール スタック:

#0 63AE80E9 wxThreadInternal::DoThreadOnExit(thread=0x2cfa978) (../../src/msw/thread.cpp:553)
#1 63B27ACF wxScopeGuardImpl1<void (*)(wxThread*) (../../include/wx/scopeguard.h:168)
#2 63B3F95B wxPrivate::OnScopeExit<wxScopeGuardImpl1<void (*)(wxThread*) (../../include/wx/scopeguard.h:67)
#3 63B27B36 wxScopeGuardImpl1<void (*)(wxThread*) (../../include/wx/scopeguard.h:166)
#4 63AE82FB wxThreadInternal::DoThreadStart(thread=0x2cfa978) (../../src/msw/thread.cpp:561)
#5 63AE83F2 wxThreadInternal::WinThreadStart(param=0x2cfa978) (../../src/msw/thread.cpp:602)
#6 75C4906A ui64tow() (C:\Windows\SysWOW64\msvcrt.dll:??)
#7 75C49147 msvcrt!iswalnum() (C:\Windows\SysWOW64\msvcrt.dll:??)
#8 76448543 UnregisterBadMemoryNotification() (C:\Windows\SysWOW64\kernel32.dll:??)
#9 00000000 0x02cfb178 in ??() (??:??)
#10 00000000    0x77e8ac69 in ??() (??:??)
#11 00000000    0x77e8ac3c in ??() (??:??)
#12 00000000    0x00000000 in ??() (??:??)
4

3 に答える 3

0

指数ポインタ (ここでexpptrは ) は、すでにオブジェクトに初期化されている必要があります。

このワンライナーは問題を解決します:

expptr = new mp_exp_t();

// call mpf_get_str()

また、VZ. GDB (GNU Debugger)が、エラーが表示されるはずのソース コードの間違った行を表示する可能性があることは正しかったです。

それだけに頼らないでください。

于 2012-09-24T15:57:41.717 に答える
0

この行で実際にクラッシュする場合 (gdb が単に失われ、後続のフレームが表示されないという無視できない可能性もあります)、threadポインター自体が NULL または無効である必要があり、これは通常の実行では発生しません。他の回答に同意してください。変数が壊れているようです。OnExit()ただし、gdb が嘘をついている場合に備えて、入力されているかどうかを確認してください。

また、クロスプラットフォーム ライブラリを使用しているため、Linux で再構築して valgrind で実行できるはずです。これにより、すべての明白な問題が特定されるはずです。

于 2012-09-20T09:34:50.423 に答える
0

new は「失敗」しません。それ自体、どこかでヒープが破損しています。

于 2012-09-19T20:33:48.413 に答える