Boost :: filesystem, std :: sort: проблема с сохранением информации о проходах сортировки

Я пытаюсь использовать std::sort на тип данных, который содержит информацию, прочитанную из boost::filesystem::dictionary_iterator, Похоже, что как алгоритм сортировки сделал n сравнения, n количество файлов в каталоге, эта информация теряется, и я в конечном итоге segfaulting. Valgrind говорит, что я использую неинициализированные значения и делаю недопустимые чтения.

Как я могу изменить свой File Тип данных или алгоритмы, чтобы информация была сохранена между проходами?

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;

struct File {
fs::path path;
fs::file_status status;
};

bool comp(const File& a, const File& b) {
static size_t count = 0;
std::cout << "Compare function called " << ++count << " times" << std::endl;
std::string a_filename = a.path.filename().native();
std::string b_filename = b.path.filename().native();
return a_filename.compare(b_filename);
}

int main() {
std::vector<File> vec;

// Read directory
fs::directory_iterator it("/etc"), end;
for (; it != end; it++) {
File f = *(new File);
f.path = it->path();
f.status = it->status();
vec.push_back(f);
}

std::sort(vec.begin(), vec.end(), comp);

// Clean up
for (std::vector<File>::iterator it = vec.begin(); it != vec.end(); it++)
delete &(*it);

return 0;
}

(Это не моя настоящая программа, но демонстрирует то же поведение.)

1

Решение

Вызов метода compare () в конце неверен, он возвращает int, который может быть равен -1, 0 или 1, например strcmp (). Вместо этого используйте простой вызов std :: less () (a_filename, b_filename). Также убедитесь, что у вас есть модульные тесты, в которых компаратор создает строго-слабый порядок, как это требуется для std :: sort.

Компаратор с внутренней проверкой:

inline bool do_compare(const File& a, const File& b)
{
/* ... */
}

bool compare(const File& a, const File& b)
{
bool const res = do_compare(a, b);
if(res)
assert(!do_compare(b, a));
return res;
}

Если определен NDEBUG (то есть assert () деактивирован), компилятор должен иметь возможность оптимизировать его до того же объема кода, что и раньше. А теперь я желаю вам много удовольствия, написав код, который сортирует имена файлов 9.png, 10.png и 11.png в указанном порядке. 😉

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]