Обновление 2: см. раздел после моего кода.
Я использую поток для вычисления PI с использованием библиотеки GMP, но каким-то образом теперь я получаю ошибку сегментации, когда 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 ??() (??:??)
wxThread::OnExit()
! - person ComFreek   schedule 20.09.2012NULL
. Кроме того, ваше утверждение, которое следует ниже, неверно. - person Nikolai Fetissov   schedule 20.09.2012outputStr
теперь размещается в стеке. - person ComFreek   schedule 20.09.2012char *data = mpz_get_str(NULL, base, gmpInt); std::string output(data); free(data);
. В моем случае ошибка сегментации была вызвана вызовомfree
, и я предположил, чтоmpz_get_str
, вероятно, выделяет память каким-то странным образом, не предоставляя никаких (очевидных) средств ее освобождения. Мне удалось обойти это с помощью MPIR в Windows и последней версии GMP в Linux. - person Mihai Todor   schedule 24.09.2012expptr
не был инициализирован (т. е. вы должныnew
это сделать, GMP не сделает это за вас!) - person ComFreek   schedule 24.09.2012new
, поскольку вы вызываете C-версию GMP API. Я ожидал бы использоватьmalloc
иfree
в этом случае, но в любом случае, я рад, что вам удалось заставить его работать. - person Mihai Todor   schedule 24.09.2012new
иdelete
, потому что, делая это, вы определенно напрашиваетесь на неприятности;) - person Mihai Todor   schedule 24.09.2012new
илиdelete
какие-либо переданные параметры. Так что это безопасно (это означает, что это не сломает что-то напрямую) использовать здесь. - person ComFreek   schedule 24.09.2012