0

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

public:
    typedef stdext::hash_map<wchar_t*, MyClass*, ltstr> transaction_hash_map; 
private:
    transaction_hash_map _transactions;

在清理期间,我试图遍历此列表并释放任何仍未释放的对象。但是,我在这里的for线上得到了一个 AV:

for (transaction_hash_map::const_iterator it = _transactions.begin(); it != _transactions.end(); it++)
{   
            MyClass* item = (MyClass*)it->second;

    if (item != NULL)
    {
        item->End();
        delete item;
    }       
}

回复: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;
        }
    };

堆栈在 begin() 方法中显示它。有任何想法吗?

4

3 回答 3

0

据我了解,您正在检查指针是否为 NULL 以查找可能尚未删除的“剩余”项目。但是对于您在清理阶段之前删除的项目,您是否将指针设置为 NULL?

请注意,当您删除对象时,指针不会自动设置为 NULL。因此,如果您不这样做,您会尝试两次删除同一个对象(因为您的 if 语句将始终为真),可能会导致访问冲突。

下面的代码是导致双重删除的示例。如果您取消注释将指针设置为 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;
}

编辑:我看到你在for线上得到了错误。所以我想知道...

显然,您有一个包含_transactions成员的MyClass ,它是一个以MyClass指针作为数据类型的哈希表。如果清理代码是在MyClass的成员函数中执行的,您是否有可能(出于某种原因)删除拥有您正在迭代的_transactions的MyClass实例?

在这种情况下,由于this对象不再存在,您可能会在for内的it++语句中遇到错误。(当然,错误也可能在其他地方,比如删除本身。)

于 2009-09-29T20:30:51.767 回答
0

我能想到的一件可能的事情是,在您尝试遍历 hash_map 之前,您的类已经在其他地方被删除,因此 begin() 将在垃圾上运行。值得一试...

另外 - 你的 wchar_t* 是如何被分配/释放的?您显示的代码似乎没有处理这些。我不确定这会如何在您的循环中造成麻烦,但值得考虑。

一件小事——你不应该需要(MyClass*)演员表。hash_map 的值无论如何都应该是该类型,因此让编译器强制执行类型检查比使用显式强制转换绕过它们要好。不过,这不应该在这里产生任何影响。

于 2009-09-29T21:00:55.427 回答
0

确保在 for 循环之后调用 _transactions.clear()。

于 2009-09-30T01:48:42.930 回答