更新 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:WindowsSysWOW64msvcrt.dll:??)
#7 75C49147 msvcrt!iswalnum() (C:WindowsSysWOW64msvcrt.dll:??)
#8 76448543 UnregisterBadMemoryNotification() (C:WindowsSysWOW64kernel32.dll:??)
#9 00000000 0x02cfb178 in ??() (??:??)
#10 00000000 0x77e8ac69 in ??() (??:??)
#11 00000000 0x77e8ac3c in ??() (??:??)
#12 00000000 0x00000000 in ??() (??:??)
new 不会"失败",本身,你在某处有堆损坏。
如果它真的在这一行上崩溃(gdb 只是丢失并且不显示后续帧的可能性也不容忽视),那么thread
指针本身必须是 NULL 或无效的,这在正常执行中不会发生,所以我同意另一个回复:似乎有些东西破坏了你的变量。但是请检查您的OnExit()
是否被输入,以防万一 gdb 在撒谎。
当你使用跨平台库时,你应该能够在Linux下重建并在valgrind下运行它,这应该可以指出所有明显的问题。
指针(此处expptr
)必须已经初始化为对象。
这个单行代码解决了这个问题:
expptr = new mp_exp_t();
// call mpf_get_str()
我还想指出,VZ.是正确的,GDB(GNU调试器)可以显示错误的源代码行,错误应该出现在其中。
所以不要只依赖它。