So I've got this function which will take a list of string pairs and generate a COMDLG_FILTERSPEC array.
pairs are as such: first = "All Types"
second = "*.*"
The function works however I get buffer overruns as shown here:
I also get this nice message telling me I'll get buffer overruns
I have no idea how to fix this or why it's overrunning. Can anyone help?
Here's the code:
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;
}
Any help is appreciated, thanks.
The problem is not due to a buffer overflow, but rather that you are simply not null-terminating the
wchar[]
strings you are adding to the filter.Per the
std::basic_string::copy()
documentation on cppreference.com:So, you need to add those null terminators to your strings, eg:
Alternatively, you can combine all of the
new[]
'ed memory into a single allocation for easier cleanup, eg:However, if the contents of the
std::list
will persist beyond the lifetime of theCOMDLG_FILTERSPEC
, then you don't need tonew[]
any memory for the strings at all, just use the existingstd::wstring
memory as-is, eg:In which case, you should consider returning a
std::unique_ptr<COMDLG_FILTERSPEC[]>
rather than a rawCOMDLG_FILTERSPEC*
pointer, eg:Or, return a
std::vector
instead, eg: