C++:在 erase(*it) 之后使用 dense_hash_set 的迭代器
C++: using an iterator of dense_hash_set after erase(*it)
我有this C++ code file
这是 FOSS
根据外籍人士执照。当 运行 cppcheck
在代码上我得到这个错误:
[google_hash.cpp:137] -> [google_hash.cpp:141]: (error) Iterator 'it' used after element has been erased.
有问题的代码是:
74 #if (FCS_WHICH_STATES_GOOGLE_HASH == FCS_WHICH_STATES_GOOGLE_HASH__SPARSE)
75 typedef sparse_hash_set<char *, state_hash, state_equality> StatesGoogleHash;
76 #else
77 typedef dense_hash_set<char *, state_hash, state_equality> StatesGoogleHash;
78 #endif
.
.
.
131 extern void fc_solve_states_google_hash_foreach(
132 fcs_states_google_hash_handle void_hash,
133 bool (*should_delete_ptr)(void *key, void *context), void *context)
134 {
135 StatesGoogleHash *hash = (StatesGoogleHash *)void_hash;
136
137 for (StatesGoogleHash::iterator it = hash->begin(); it != hash->end(); ++it)
138 {
139 if (should_delete_ptr(*(it), context))
140 {
141 hash->erase(it);
142 }
143 }
144 }
它利用了
http://goog-sparsehash.sourceforge.net/doc/sparse_hash_set.html
或 http://goog-sparsehash.sourceforge.net/doc/dense_hash_set.html .
现在,这些文件说
Validity of Iterators
insert() invalidates all iterators, as does resize().
erase() is guaranteed not to invalidate any iterators.
所以我的问题是 - 我是否正确安全地使用了集合的迭代器
(并且 cppcheck 发出了误报),或者如果没有 - 应该如何
代码修复了吗?
我们将不胜感激。
从 cppcheck 认为在 iterator
上调用 erase
的 API 使迭代器无效的意义上说,这是误报。这是它使用的规则,因为这是一个明智的 API.
然后对于这段代码,++it
似乎是有效的,因为:
This is implemented by making erase() not resize the hashtable. If you desire maximum space efficiency, you can call resize(0) after a string of erase() calls, to force the hashtable to resize to the smallest possible size.
这似乎意味着如果您不在擦除之间调用 resize(0)
,迭代器可能会遇到已删除的对象。这里很好,因为擦除是在同一个循环中完成的。
此代码通过不明显且不使用标准模式来隐藏其行为这一事实无济于事。
我有this C++ code file 这是 FOSS 根据外籍人士执照。当 运行 cppcheck 在代码上我得到这个错误:
[google_hash.cpp:137] -> [google_hash.cpp:141]: (error) Iterator 'it' used after element has been erased.
有问题的代码是:
74 #if (FCS_WHICH_STATES_GOOGLE_HASH == FCS_WHICH_STATES_GOOGLE_HASH__SPARSE)
75 typedef sparse_hash_set<char *, state_hash, state_equality> StatesGoogleHash;
76 #else
77 typedef dense_hash_set<char *, state_hash, state_equality> StatesGoogleHash;
78 #endif
.
.
.
131 extern void fc_solve_states_google_hash_foreach(
132 fcs_states_google_hash_handle void_hash,
133 bool (*should_delete_ptr)(void *key, void *context), void *context)
134 {
135 StatesGoogleHash *hash = (StatesGoogleHash *)void_hash;
136
137 for (StatesGoogleHash::iterator it = hash->begin(); it != hash->end(); ++it)
138 {
139 if (should_delete_ptr(*(it), context))
140 {
141 hash->erase(it);
142 }
143 }
144 }
它利用了 http://goog-sparsehash.sourceforge.net/doc/sparse_hash_set.html 或 http://goog-sparsehash.sourceforge.net/doc/dense_hash_set.html .
现在,这些文件说
Validity of Iterators
insert() invalidates all iterators, as does resize().
erase() is guaranteed not to invalidate any iterators.
所以我的问题是 - 我是否正确安全地使用了集合的迭代器 (并且 cppcheck 发出了误报),或者如果没有 - 应该如何 代码修复了吗?
我们将不胜感激。
从 cppcheck 认为在 iterator
上调用 erase
的 API 使迭代器无效的意义上说,这是误报。这是它使用的规则,因为这是一个明智的 API.
然后对于这段代码,++it
似乎是有效的,因为:
This is implemented by making erase() not resize the hashtable. If you desire maximum space efficiency, you can call resize(0) after a string of erase() calls, to force the hashtable to resize to the smallest possible size.
这似乎意味着如果您不在擦除之间调用 resize(0)
,迭代器可能会遇到已删除的对象。这里很好,因为擦除是在同一个循环中完成的。
此代码通过不明显且不使用标准模式来隐藏其行为这一事实无济于事。