Compare these two largely identical functions. In the first, the memory for buff is allocated using _alloca. This works fine. In the second, calloc and free are used instead of _alloca. This crashes.
The weird thing is that I use the calloc/free technique in almost every other GMP wrapping function I have and they all work. Here they don’t. Any ideas?
1:
#define Z(x) mpz_t (x); mpz_init( (x) ); #define BUFF_SIZE (1024 * 32) BSTR __stdcall IBIGDIV(BSTR p1, BSTR p2 ) { USES_CONVERSION; Z(n1); Z(n2); Z(res); char * buff = (char *) _alloca( mpz_sizeinbase( res, 10 ) + 2 ); LPSTR sNum1 = W2A( p1 ); LPSTR sNum2 = W2A( p2 ); mpz_set_str( n1, sNum1, 10 ); mpz_set_str( n2, sNum2, 10 ); if ( mpz_sgn( n2 ) != 0 ) { mpz_div( res, n1, n2 ); mpz_get_str(buff, 10, res); } else { strcpy( buff, '-0' ); } BSTR bResult = _com_util::ConvertStringToBSTR( buff ); return bResult; }
2:
#define Z(x) mpz_t (x); mpz_init( (x) ); #define BUFF_SIZE (1024 * 32) BSTR __stdcall IBIGDIV(BSTR p1, BSTR p2 ) { USES_CONVERSION; Z(n1); Z(n2); Z(res); char * buff = (char *) calloc( mpz_sizeinbase( res, 10 ) + 2, sizeof( char ) ); LPSTR sNum1 = W2A( p1 ); LPSTR sNum2 = W2A( p2 ); mpz_set_str( n1, sNum1, 10 ); mpz_set_str( n2, sNum2, 10 ); if ( mpz_sgn( n2 ) != 0 ) { mpz_div( res, n1, n2 ); mpz_get_str(buff, 10, res); } else { strcpy( buff, '-0' ); } BSTR bResult = _com_util::ConvertStringToBSTR( buff ); free( buff ); return bResult; }
Add logging and dump everything along the way to find what goes wrong. This is usually more efficient than trying to guess.