繁体   English   中英

c++ COM COMDLG_FILTERSPEC 阵列溢出

[英]c++ COM COMDLG_FILTERSPEC array overrun

所以我有这个 function 它将获取一个字符串对列表并生成一个 COMDLG_FILTERSPEC 数组。 对是这样的: first = "All Types" second = "*.*"

function 工作,但是我得到缓冲区溢出,如下所示:

在此处输入图像描述

我也收到了这条好消息,告诉我我会遇到缓冲区溢出在此处输入图像描述

我不知道如何解决这个问题或为什么它会超支。 任何人都可以帮忙吗?

这是代码:

COMDLG_FILTERSPEC * CreateFILTERSPEC(std::list<std::pair<std::wstring, std::wstring>> _filters) {

    //TODO: Causes memory leak on deletion. Fix it.

    COMDLG_FILTERSPEC* filterSpecs = new COMDLG_FILTERSPEC[_filters.size()];

    int i = 0;
    for (std::pair<std::wstring, std::wstring> filter : _filters) {


        PWSTR f1_p = new wchar_t[filter.first.length()];
        filter.first.copy(f1_p, filter.first.length());

        PWSTR f2_p = new wchar_t[filter.second.length()];
        filter.second.copy(f2_p, filter.second.length());

        COMDLG_FILTERSPEC fs = { f1_p, f2_p };

        filterSpecs[i] = fs;
        i++;
    }

    return filterSpecs;

}

任何帮助表示赞赏,谢谢。

问题不是由于缓冲区溢出,而是您根本没有对要添加到过滤器的wchar[]字符串进行空终止。

根据 cppreference.com 上的std::basic_string::copy()文档

将 substring [pos, pos+count)复制到dest指向的字符串。 如果请求的 substring 持续超过字符串的末尾,或者如果count == npos ,则复制的 substring 为[pos, size()) 结果字符串不是以空值结尾的。

因此,您需要将那些 null 终止符添加到您的字符串中,例如:

COMDLG_FILTERSPEC* CreateFILTERSPEC(std::list<std::pair<std::wstring, std::wstring>> _filters) {

    COMDLG_FILTERSPEC* filterSpecs = new COMDLG_FILTERSPEC[_filters.size()];

    int i = 0;
    for (auto &filter : _filters) {

        PWSTR f1_p = new wchar_t[filter.first.length() + 1]; // <-- note the +1 !
        filter.first.copy(f1_p, filter.first.length());
        f1_p[filter.first.length()] = L'\0'; // <-- add this !

        PWSTR f2_p = new wchar_t[filter.second.length() + 1]; // <-- note the +1 !
        filter.second.copy(f2_p, filter.second.length());
        f2_p[filter.second.length()] = L'\0'; // <-- add this !

        COMDLG_FILTERSPEC fs = { f1_p, f2_p };

        filterSpecs[i] = fs;
        ++i;
    }

    return filterSpecs;
}
COMDLG_FILTERSPEC *filterSpecs = CreateFILTERSPEC(filters);

// use filterSpecs as needed ...

for(int i = 0; i < filters.size(); ++i) {
    delete[] filterSpecs[i].pszName;
    delete[] filterSpecs[i].pszSpec;
};
delete[] filterSpecs;

如果std::list的内容将持续超过COMDLG_FILTERSPEC的生命周期,那么您根本不需要new[]任何 memory 字符串,只需按原样使用现有的std::wstring memory,例如:

COMDLG_FILTERSPEC * CreateFILTERSPEC(const std::list<std::pair<std::wstring, std::wstring>> &_filters) {

    COMDLG_FILTERSPEC* filterSpecs = new COMDLG_FILTERSPEC[_filters.size()];

    int i = 0;
    for (const auto &filter : _filters) {
        COMDLG_FILTERSPEC fs = { filter.first.c_str(), filter.second.c_str() };
        filterSpecs[i++] = fs;
    }

    return filterSpecs;
}
COMDLG_FILTERSPEC *filterSpecs = CreateFILTERSPEC(filters);

// use filterSpecs as needed ...

delete[] filterSpecs;

话虽如此,您应该考虑返回std::unique_ptr<COMDLG_FILTERSPEC[]>而不是原始COMDLG_FILTERSPEC*指针,例如:

std::unique_ptr<COMDLG_FILTERSPEC[]> CreateFILTERSPEC(const std::list<std::pair<std::wstring, std::wstring>> &_filters) {

    auto filterSpecs = std::make_unique<COMDLG_FILTERSPEC[]>(_filters.size());

    int i = 0;
    for (const auto &filter : _filters) {
        COMDLG_FILTERSPEC fs = { ... };
        filterSpecs[i++] = fs;
    }

    return filterSpecs;
}
auto filterSpecs = CreateFILTERSPEC(filters);

// use filterSpecs.get() as needed ...

// the COMDLG_FILTERSPEC memory is freed automatically when
// filterSpecs goes out of scope...

或者,返回一个std::vector ,例如:

std::vector<COMDLG_FILTERSPEC> CreateFILTERSPEC(const std::list<std::pair<std::wstring, std::wstring>> &_filters) {

    std::vector<COMDLG_FILTERSPEC> filterSpecs(_filters.size());

    int i = 0;
    for (const auto &filter : _filters) {
        COMDLG_FILTERSPEC fs = { ... };
        filterSpecs[i++] = fs;
    }

    return filterSpecs;
}
auto filterSpecs = CreateFILTERSPEC(filters);

// use filterSpecs.data() as needed ...

// the COMDLG_FILTERSPEC memory is freed automatically when
// filterSpecs goes out of scope...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM