diff --git a/cocos/base/CCConsole.cpp b/cocos/base/CCConsole.cpp index 0a48afa7ae..b6a085bc06 100644 --- a/cocos/base/CCConsole.cpp +++ b/cocos/base/CCConsole.cpp @@ -128,26 +128,39 @@ namespace { { int bufferSize = MAX_LOG_LENGTH; char* buf = nullptr; - + int nret = 0; do { buf = new (std::nothrow) char[bufferSize]; if (buf == nullptr) - return; // not enough memory - - int ret = vsnprintf(buf, bufferSize - 3, format, args); - if (ret < 0) - { - bufferSize *= 2; - - delete [] buf; + return; + /* + pitfall: The behavior of vsnprintf between VS2013 and VS2015/2017 is different + VS2013 or Unix-Like System will return -1 when buffer not enough, but VS2015/2017 will return the actural needed length for buffer at this station + The _vsnprintf behavior is compatible API which always return -1 when buffer isn't enough at VS2013/2015/2017 + Yes, The vsnprintf is more efficient implemented by MSVC 19.0 or later, AND it's also standard-compliant, see reference: http://www.cplusplus.com/reference/cstdio/vsnprintf/ + */ + nret = vsnprintf(buf, bufferSize - 3, format, args); + if (nret >= 0) + { // VS2015/2017 + if (nret <= bufferSize - 3) + {// success, so don't need to realloc + break; + } + else + { + bufferSize = nret + 3; + delete[] buf; + } + } + else // < 0 + { // VS2013 or Unix-like System(GCC) + bufferSize *= 2; + delete[] buf; } - else - break; - } while (true); - - strcat(buf, "\n"); + buf[nret] = '\n'; + buf[++nret] = '\0'; #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID __android_log_print(ANDROID_LOG_DEBUG, "cocos2d-x debug info", "%s", buf); @@ -155,7 +168,7 @@ namespace { #elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT int pos = 0; - int len = strlen(buf); + int len = nret; char tempBuf[MAX_LOG_LENGTH + 1] = { 0 }; WCHAR wszBuf[MAX_LOG_LENGTH + 1] = { 0 };