C++ ExtractIconEx:工作正常,但偶尔会崩溃
我正在从文件中提取图标,并在对话框中显示它们C++ ExtractIconEx:工作正常,但偶尔会崩溃,c++,arrays,winapi,icons,allocation,C++,Arrays,Winapi,Icons,Allocation,我正在从文件中提取图标,并在对话框中显示它们 const LPCWSTR path = L"c:\path\to\file"; const UINT nIconsCheck = ExtractIconEx(path, -1, nullptr, nullptr, 0); if(nIconsCheck > 0) { HICON *iconHandles=new HICON; const UINT nIcons = ExtractIconEx(path, 0, iconHandl
const LPCWSTR path = L"c:\path\to\file";
const UINT nIconsCheck = ExtractIconEx(path, -1, nullptr, nullptr, 0);
if(nIconsCheck > 0)
{
HICON *iconHandles=new HICON;
const UINT nIcons = ExtractIconEx(path, 0, iconHandles, nullptr, nIconsCheck);
if(nIcons == nIconsCheck && nIcons != unsigned(-1))
{
IconSelect iconSelect(this); //dialog
for(UINT i=0; i<nIcons; i++)
{
qDebug() << i;
iconSelect.addIcon(QtWin::fromHICON(iconHandles[i])); //fromHICON returns QPixmap
DestroyIcon(iconHandles[i]);
}
iconSelect.exec();
}
}
const LPCWSTR path=L“c:\path\to\file”;
const UINT nIconsCheck=ExtractIconEx(路径,-1,nullptr,nullptr,0);
如果(NiconCheck>0)
{
HICON*iconHandles=新HICON;
const UINT nIcons=ExtractIconEx(路径,0,iconHandles,nullptr,niconCheck);
if(nIcons==nIconsCheck&&nIcons!=无符号(-1))
{
IconSelect IconSelect(此);//对话框
对于(UINT i=0;i
在这里,您只分配一个HICON
对象。如果给定文件中有多个图标,则对ExtractIconEx()
的下一次调用将通过写入分配的内存来创建缓冲区溢出。您已进入未定义行为的黑暗世界
要解决此问题,您可以使用如下方法:
std::vector<HICON> iconHandles(nIconsCheck);
const UINT nIcons = ExtractIconEx(path, 0, iconHandles.data(), nullptr, iconHandles.size());
iconHandles.resize(nIcons); // Resize to the actual number of icons.
// Instead of: if(nIcons == nIconsCheck && nIcons != unsigned(-1))
if(!iconHandles.empty())
{
// Use icons
}
std::向量iconHandles(NiconCheck);
const UINT nIcons=ExtractIconEx(path,0,iconHandles.data(),nullptr,iconHandles.size());
iconHandles.resize(nIcons);//调整到图标的实际数量。
//而不是:if(nIcons==nIconsCheck&&nIcons!=未签名(-1))
如果(!iconHandles.empty())
{
//使用图标
}
与手动分配相比,这有一个优势,即您不需要删除分配的内存。向量
析构函数将在作用域结束时自动执行此操作。尽管您仍然必须为每个图标句柄调用销毁图标()
。从您链接的文档:
指向图标句柄数组的指针,该数组接收从文件中提取的大图标的句柄。如果此参数为NULL,则不会从文件中提取大图标
您只给它一个指向一个图标句柄的指针
分配一个与函数期望的大小一样大的数组;从外观上看,这意味着niconCheck
元素。正如zett42所说,向量很适合这样做。您确定iconHandles
足够大,可以容纳所有niconCheck
句柄吗?(我不是C++程序员,我不经常使用ExcExcCouX,但这似乎是代码的问题。)HICON*iconHandles=new HICON;
为单个HICON句柄分配了足够的内存,而不是一个句柄数组。您需要分配足够的内存来接收@AndreasRejbrand指出的至少niconcheck
句柄。谢谢,就这样!更改为HICON*iconHandles=new HICON[nIcons];
(并添加了delete[]iconHandles;
循环后)我建议用std::vector iconHandles(niconCheck);const UINT nIcons=extracticonnex(path,0,iconHandles.data(),nullptr,iconHandles.size());替换手动分配;
如果它偶尔崩溃,它不是“正常工作”!谢谢!我想补充一下如果(nIcons==NiconCheck&&nIcons!=unsigned(-1))
check在正确分配时是不必要的。@但是我已经添加了如何更改条件。引用中没有任何内容表明ExtractIconEx()的返回值
可以是-1
。虽然返回值可能小于nIcons
参数,但如果不是所有图标都能成功提取,那么我会相应地调整向量大小。在第一次和第二次调用ExtractIconEx
之间也可能存在toctou竞争条件。
HICON *iconHandles=new HICON;
std::vector<HICON> iconHandles(nIconsCheck);
const UINT nIcons = ExtractIconEx(path, 0, iconHandles.data(), nullptr, iconHandles.size());
iconHandles.resize(nIcons); // Resize to the actual number of icons.
// Instead of: if(nIcons == nIconsCheck && nIcons != unsigned(-1))
if(!iconHandles.empty())
{
// Use icons
}