如何在 Win32 C++ 项目中使用 _malloca 而不是 _alloca?

问题描述 投票:0回答:2

我正在更新一个旧的 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)
c++ malloc bstr alloca
2个回答
1
投票

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)))))

0
投票

_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
的一个版本 具有安全增强功能,如中的安全功能所述 显像管.

返回值

_malloca
例程返回一个指向分配空间的空指针, 它适合存储任何类型的对象。如果尺寸 为 0,
_malloca
分配一个零长度项并返回一个有效的 指向该项目的指针。

如果大小大于

_ALLOCA_S_THRESHOLD
,则
_malloca
会尝试 在堆上分配,如果无法分配空间则返回空指针 分配。如果大小小于或等于
_ALLOCA_S_THRESHOLD
,则
_malloca
尝试在栈上分配,如果无法分配空间,会产生栈溢出异常。堆栈 溢出异常不是 C++ 异常;这是一个结构化的异常。 您必须使用 Structured,而不是使用 C++ 异常处理 异常处理 (SEH) 捕获此异常。

备注

如果请求超过给定的特定大小(以字节为单位),则

_malloca
从程序堆栈或堆中分配 size 字节
_ALLOCA_S_THRESHOLD
_malloca
_alloca
之间的区别在于,
_alloca
始终在堆栈上分配,无论大小如何。 与
_alloca
不同,它不需要或允许调用 free 到 free 如此分配的内存,
_malloca
需要使用
_freea
来释放 记忆。在调试模式下,
_malloca
始终从堆中分配内存。

© www.soinside.com 2019 - 2024. All rights reserved.