int gb2Utf8(const char* source, int sourceLen, void *target, int targetLen)
{
int result = 0;
int bufLen = strlen(source) * 2;
wchar_t *buffer = (wchar_t *)malloc(bufLen);
if (!buffer)
{
result = 1;
goto RETURN;
}
//GB18030 code page: 54936
int m2wResult = MultiByteToWideChar(54936, MB_ERR_INVALID_CHARS, source, -1, buffer, bufLen);
if (!m2wResult)
{
result = 2;
goto RETURN;
}
int w2mResult = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, buffer, -1, (char *)target, targetLen, NULL, NULL);
if (!w2mResult)
{
result = 3;
goto RETURN;
}
RETURN:
free(buffer);
return result;
}
When program runs to free(buffer), it will crash, but I don’t know why.
If modify bufLen to a constant value, or remove MultiByteToWideChar function, it won’t crash, I also don’t know why.
This is the call stack when crash:
msvcr100d.dll!_free_dbg_nolock(void * pUserData, int nBlockUse) Line 1376 + 0x3b bytes C++
msvcr100d.dll!_free_dbg(void * pUserData, int nBlockUse) Line 1265 + 0xd bytes C++
msvcr100d.dll!free(void * pUserData) Line 49 + 0xb bytes C++
New.exe!gb2Utf8(const char * source, int sourceLen, void * target, int targetLen) Line 156 + 0xc bytes C++
New.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 29 + 0x11 bytes C++
New.exe!__tmainCRTStartup() Line 547 + 0x2c bytes C
New.exe!wWinMainCRTStartup() Line 371 C
kernel32.dll!7509339a()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!77979ef2()
ntdll.dll!77979ec5()
The last parameter for
MultiByteToWideChar()is the number of characters in the widechar buffer and not the number of bytes. You pass the number of bytes, the function probably writes over the actual buffer andfree()checks for that when compiled in debug mode.And as Jeeva mentioned, the proper way to call this function is by calling it once with NULL output buffer, allocate the buffer with the requested size and then call it again.