Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在哈希映射中迭代时的AV?_C++_Stl_Hashmap_Access Violation - Fatal编程技术网

C++ 在哈希映射中迭代时的AV?

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 {

_transaction是我的类的私有成员变量,声明为:

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;
}