根据OLE转换宏的MSDN文档,如果我们在for循环中使用宏,例如,最终可能会在堆栈上分配更多内存导致堆栈溢出。
这是MSDN上提供的示例
void BadIterateCode(LPCTSTR* lpszArray)
{
USES_CONVERSION;
for (int ii = 0; ii < 10000; ii++)
pI->SomeMethod(ii, T2COLE(lpszArray[ii]));
}
在上面的示例中,T2COLE用于for循环,这可能导致堆栈溢出,为避免这种情况,方法调用被封装到这样的函数中
void CallSomeMethod(int ii, LPCTSTR lpsz)
{
USES_CONVERSION;
pI->SomeMethod(ii, T2COLE(lpsz));
}
void MuchBetterIterateCode2(LPCTSTR* lpszArray)
{
for (int ii = 0; ii < 10000; ii++)
CallSomeMethod(ii, lpszArray[ii]);
}
我们可以将LPCTSTR发送到另一个函数,而不是像这样封装整个方法,
LPCOLESTR CallSomeMethod(LPCTSTR lpsz)
{
USES_CONVERSION;
return T2COLE(lpsz);
}
void BadIterateCode(LPCTSTR* lpszArray)
{
for (int ii = 0; ii < 10000; ii++)
pI->SomeMethod(ii, CallSomeMethod(lpszArray[ii]));
}
任何人都可以告诉我,如果它是安全使用OLE宏还是我们可能会遇到堆栈溢出?
使用上述方法会有其他问题吗?
答案 0 :(得分:0)
第三个示例将不起作用,因为一旦从函数返回,方法中创建的T2COLE
对象将被销毁。正如您在问题中所指出的那样,对象是在堆栈上创建的,并且通常的堆栈规则适用于这种情况 - 一旦您超出范围,对象将被销毁,并且您将在第3个访问垃圾数据情况下。
第二种情况是使用数据而不触发堆栈溢出的正确机制,因为从函数返回时,T2COLE
分配的内存将被释放。
我不知道T2COLE
的实现是如何工作的,但是在C中,你可以通过使用遇到同样问题的alloca
函数来实现相同的行为 - 只要你从函数返回时,您应该将指针及其指向的数据视为无效。