我正在更新一个旧的 C++ DLL 项目。对于导出的函数之一,有
BSTR __stdcall j2cs( const long lJulian, int bDMY, BSTR sDelim ) {
USES_CONVERSION;
int iDay, iMonth;
long lYear;
char chDate[20];
char chInt[10];
char * cDelim = W2A( sDelim );
W2A
宏定义为
#define W2A(lpw) (\
((_lpw = lpw) == NULL) ? NULL : (\
(_convert = (static_cast<int>(wcslen(_lpw))+1), \
(_convert>INT_MAX/2) ? NULL : \
ATLW2AHELPER((LPSTR) alloca(_convert*sizeof(WCHAR)), _lpw, _convert*sizeof(WCHAR), _acp))))
Visual Studio 2019 使用以下编译器警告标记 W2A 宏
Warning C6255 _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead.
我如何对 W2A 宏进行建议的更改?或者我应该忽略这个警告?
稍后
我的 USES_CONVERSION 宏定义为
#define USES_CONVERSION int _convert = 0; (_convert); UINT _acp = ATL::_AtlGetConversionACP() /*CP_THREAD_ACP*/; (_acp); LPCWSTR _lpw = NULL; (_lpw); LPCSTR _lpa = NULL; (_lpa)
W2A
无法更改为使用 malloc
。您必须在所有使用 free
的地方添加 W2A
。理想的替代方案是用 std::vector
代替 _alloca
。
更新宏
USES_CONVERSION
,因此它包含std::vector<WCHAR> _buffer;
并更新宏W2A
:
#define USES_CONVERSION int _convert = 0; (_convert); std::vector<WCHAR> _buffer; (_buffer); UINT _acp = ATL::_AtlGetConversionACP() /*CP_THREAD_ACP*/; (_acp); LPCWSTR _lpw = NULL; (_lpw); LPCSTR _lpa = NULL; (_lpa)
#define W2A(lpw) (\
((_lpw = lpw) == NULL) ? NULL : (\
(_convert = (static_cast<int>(wcslen(_lpw))+1), \
(_convert>INT_MAX/2) ? NULL : \
(_buffer.resize(_convert), \
ATLW2AHELPER((LPSTR) _buffer.data(), _lpw, _convert*sizeof(WCHAR), _acp)))))
_malloca()
似乎是 Microsoft Visual Studio 函数,它与 _alloca()
不同,但似乎有逻辑,如果堆栈上有足够的空间,则使用 _alloca()
或使用 malloc()
分配内存如果堆栈上没有足够的空间,则在堆上。
_malloca()
函数需要使用_freea()
函数来正确处理指向已分配内存的指针。
来自 Microsoft Learn,网址为 https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/malloca?view=msvc-170
的一个版本 具有安全增强功能,如中的安全功能所述 显像管._alloca
返回值
例程返回一个指向分配空间的空指针, 它适合存储任何类型的对象。如果尺寸 为 0,_malloca
分配一个零长度项并返回一个有效的 指向该项目的指针。_malloca
如果大小大于
,则_ALLOCA_S_THRESHOLD
会尝试 在堆上分配,如果无法分配空间则返回空指针 分配。如果大小小于或等于_malloca
,则_ALLOCA_S_THRESHOLD
尝试在栈上分配,如果无法分配空间,会产生栈溢出异常。堆栈 溢出异常不是 C++ 异常;这是一个结构化的异常。 您必须使用 Structured,而不是使用 C++ 异常处理 异常处理 (SEH) 捕获此异常。_malloca
备注
如果请求超过给定的特定大小(以字节为单位),则从程序堆栈或堆中分配 size 字节_malloca
。_ALLOCA_S_THRESHOLD
和_malloca
之间的区别在于,_alloca
始终在堆栈上分配,无论大小如何。 与_alloca
不同,它不需要或允许调用 free 到 free 如此分配的内存,_alloca
需要使用_malloca
来释放 记忆。在调试模式下,_freea
始终从堆中分配内存。_malloca