C++ 在哈希映射中迭代时的AV?
_transaction是我的类的私有成员变量,声明为:C++ 在哈希映射中迭代时的AV?,c++,stl,hashmap,access-violation,C++,Stl,Hashmap,Access Violation,_transaction是我的类的私有成员变量,声明为: public: typedef stdext::hash_map<wchar_t*, MyClass*, ltstr> transaction_hash_map; private: transaction_hash_map _transactions; 回复:什么是ltstr private: struct ltstr { enum {
public:
typedef stdext::hash_map<wchar_t*, MyClass*, ltstr> transaction_hash_map;
private:
transaction_hash_map _transactions;
回复:什么是ltstr
private:
struct ltstr
{
enum
{
bucket_size = 8,
min_buckets = 16
};
bool operator()(wchar_t* s1, wchar_t* s2) const
{
return wcscmp( s1, s2 ) < 0;
}
size_t operator()(wchar_t *s1) const
{
size_t h = 0;
wchar_t *p = const_cast<wchar_t*>(s1);
wchar_t zero = L'\0';
while ( *p != zero ) h = 31 * h + (*p++);
return h;
}
};
private:
结构ltstr
{
枚举
{
桶大小=8,
最小桶数=16
};
布尔运算符()(wchar\u t*s1,wchar\u t*s2)常量
{
返回wcscmp(s1,s2)<0;
}
size_t运算符()(wchar_t*s1)常量
{
尺寸h=0;
wchar_t*p=常数(s1);
wchar_t zero=L'\0';
而(*p!=0)h=31*h+(*p++);
返回h;
}
};
堆栈在begin()方法中显示它。有什么想法吗?据我所知,您正在针对可能尚未删除的“剩余”项目检查指针是否为空。但是对于在清理阶段之前删除的项目,是否将指针设置为NULL 请注意,删除对象时,指针不是自动设置为空的。因此,如果您不这样做,您将尝试删除同一对象两次(因为您的if语句将始终为true),那么什么会导致访问冲突呢 下面的代码是导致双重删除的示例。如果取消注释将指针设置为NULL的行,则可以修复此问题
#include <cstddef>
struct Item {};
int main()
{
Item * p = new Item();
delete p;
//If you don't make the pointer null...
//p = NULL;
if (p != NULL)
//You delete the object twice.
delete p;
}
#包括
结构项{};
int main()
{
项目*p=新项目();
删除p;
//如果不将指针设为空。。。
//p=零;
如果(p!=NULL)
//删除对象两次。
删除p;
}
编辑:我看到您在for行中得到了正确的错误。所以我想知道
显然,您有一个包含_transactions成员的MyClass,它是一个以MyClass指针作为数据类型的哈希表。如果清理代码是在MyClass的成员函数中执行的,那么是否可能(出于某种原因)正在删除拥有您正在迭代的_事务的MyClass实例
在这种情况下,您可能会在for中的it++语句中得到错误,因为this对象不再存在。(当然,错误也可能发生在其他地方,比如delete本身。)我能想到的一件可能的事情是,在您尝试遍历hash_映射之前,您的类已经在其他地方被删除了,因此begin()将对垃圾进行操作。值得一看 另外-您的wchar\u t*是如何分配/释放的?您显示的代码似乎没有处理这些问题。我不确定这将如何在您的循环中造成麻烦,但值得考虑
一件小事-你不应该需要
(MyClass*)
强制转换。哈希映射的值无论如何都应该是该类型的,因此让编译器强制执行类型检查比通过显式转换绕过类型检查更好。不过,这在这里不会有任何区别。请确保在for循环之后调用_transactions.clear()。您忽略的代码没有问题,实际上是导致错误的常见原因。例如,如果您正在从哈希表中删除一项,但没有正确设置它(迭代器)(当然取决于哈希实现)。您确定没有尝试从已删除的对象中清除映射吗?谢谢大家,我编辑了我的文章以包含更多代码。只是想澄清一下,在WINDBG中,AV显示了hash_映射本身的begin()方法的内部。为什么MyClass很重要。作为练习,即使我删除for循环中的部分,它仍然是AV的。谢谢,我确保了wchar_t*被正确地释放(它们实际上是由用户从技术上交给我的,但在我的情况下,它们被释放了)。我的hash_映射不应该在其他地方删除,因为我将它声明为私有成员,它应该在堆栈上(但可能我的假设是错误的?),但如果类本身已被删除,并且您稍后尝试通过指向其旧位置的指针访问它,第一件可能失败的事情可能是在begin()中构造迭代器的哈希。只是一个想法,因为你在这里发布的代码看起来很好。标记这个答案,因为它最接近问题。当类被创建时,它被创建为它的基类型,而不是我的类。因此,当它运行“cleanup”时,我将基类型强制转换为MyClass,从而产生迭代器垃圾。
#include <cstddef>
struct Item {};
int main()
{
Item * p = new Item();
delete p;
//If you don't make the pointer null...
//p = NULL;
if (p != NULL)
//You delete the object twice.
delete p;
}