Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ ExtractIconEx:工作正常,但偶尔会崩溃_C++_Arrays_Winapi_Icons_Allocation - Fatal编程技术网

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
}