std::map to std::list leads to SIGSEGV
std::map to std::list leads to SIGSEGV
我想在将 std::map 转换为 std::list 时节省 RAM。因此,我必须删除两者之间的每个元素。但我得到了一个SIGSEGV。
template <class U>
auto ConvertFlatSegmentsMapToList(std::map<std::string /* relative_path */, U>& differences_map, std::list<U>& differences_list) -> void {
for (auto& i:differences_map) {
differences_list.push_back(i.second);
// differences_map.erase(i.first);//TODO: SIGSEGV
}
}
怎么做?
如果要节省内存,请不要使用std::map
,也不要使用std::list
- 使用std::vector
; 或者更好的是 - 不要使用单独的字符串,应用重复数据删除等。
话虽如此,并回答您的问题:从映射中删除元素会使映射中的迭代器无效 - 并且 ranged-for 循环实际上基于迭代器。所以 - 你不能在你的循环期间删除。循环后使用differences_map.clear()
。您还应该注意,单个元素删除在时间上比清除整个地图要昂贵得多。
如果你的内存非常有限,以至于你不能同时拥有完整的地图和完整的列表,那么你只是使用了错误的数据结构 - 因为,就像我说的,这两者都是相当浪费的。不过,如果你坚持,你可以反复将*differences_map.begin()
插入到列表中,然后将其从映射中删除(每次在迭代器失效后再次获取.begin()
(。
正如优素福评论的那样,您可以在 https://stackoverflow.com/a/8234813/1142788 找到解决方案。我已经将其改编为我的例子。(需要 C++11 支持(
template <class U>
auto ConvertFlatSegmentsMapToList(std::map<std::string /* relative_path */, U>& differences_map, std::list<U>& differences_list) -> void {
std::clog << "differences_map: " << differences_map.size() << std::endl; // e.g. 6
std::clog << "differences_list: " << differences_list.size() << std::endl; // e.g. 0
for (auto i = differences_map.cbegin(); i != differences_map.cend(); i = differences_map.erase(i)) {
differences_list.push_back(i->second);
}
std::clog << "differences_map: " << differences_map.size() << std::endl; // e.g. 0
std::clog << "differences_list: " << differences_list.size() << std::endl; // e.g. 6
}
你可以考虑将std::shared_ptr
存储在你的map
、list
或其他什么。 然后,您可以廉价且轻松地复制它们,而无需复制基础数据。 您仍然可以获得(或多或少(值语义,并且不需要手动管理对象生存期。
相关文章:
- std::bind to void* to std::function
- std::time_point from and to std::string
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- Port pthread_cond_broadcast to std::atomic
- from std::vector to adept::avector
- File to std::string_view
- 如何修复以下错误"no match for call to '(std::tr1::shared_ptr<_iobuf*>) (FILE*&)'"
- std::map to std::list leads to SIGSEGV
- std::bind to a std::variant 包含多个 std::函数类型
- NSMutableArray to std::vector
- 将 2D 数组插入 std::vector 时"cannot convert from 'const GLfloat [12]' to '_Objty'"错误消息
- 使用 std::min "no matching function for call to ‘min(<brace-enclosed initializer list>)’"时出错
- 返回"Cannot convert from 'std::ofstream {aka std::basic_ofstream<char>}' to bool"错误
- reinterpret_cast std::function* to and from void*
- std::string to std::regex
- 使用命名空间 std 时C++ "Reference to overloaded function"错误
- Copy std::vector to boost::interprocess::vector
- BOOST :: lexical_cast to std ::字符串失败
- C++ std::vector to JSON Array with rapidjson
- 最快的方式 std::vector<Derived> to std::vector<Base>