Pergunta

_transaction é uma variável membro privado da minha classe, declarada como:

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

Durante a limpeza Eu estou tentando para percorrer esta lista e liberar todos os objetos ainda não-liberto. No entanto, eu estou recebendo um AV no linha aqui:

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

Re:? O que é 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;
        }
    };

Os pilha mostra-o dentro do método begin (). Alguma idéia?

Foi útil?

Solução

Uma possível coisa que eu posso pensar é que sua classe já foi eliminado em outros lugares antes de tentar percorrer a hash_map, e, assim, começar () estará operando no lixo. Worth um cheque ...

Além disso - como são sua wchar_t * ficando alocados / liberados? O código que você mostrou não parece estar lidando com aqueles. Eu não sei como isso poderia causar problemas em sua malha, mas vale a pena pensar.

Uma coisa menor - você não deve precisar o elenco (MyClass*). Os valores da hash_map deve ser daquele tipo de qualquer maneira, por isso é mais agradável para deixar o compilador impor verificações de tipo do que, possivelmente, desvio-los com uma conversão explícita. Isso não deveria estar fazendo alguma diferença aqui embora.

Outras dicas

Como eu entendo que você está verificando o ponteiro contra NULL para os "remanescentes" itens que talvez não tenham sido eliminados ainda. Mas para os itens que você excluir antes de seu estágio de limpeza, você definir o ponteiro para NULL?

Observe que quando você excluir um objeto o ponteiro é não automaticamente definida para NULL. Então, se você não está fazendo que você está tentando excluir o mesmo objeto duas vezes (porque o seu comando if será sempre true), o que poderia causar uma violação de acesso.

O código a seguir é um exemplo que provoca uma dupla eliminação. Ele pode ser corrigido se você remover o comentário da linha que define o ponteiro para 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;
}

EDIT: Vejo que você está recebendo o erro exatamente no line. Então, eu estou pensando ...

Ao que parece ter um MyClass que contém um _transactions membro, que é uma tabela hash com MyClass ponteiros como o tipo de dados. Se o código de limpeza é efectuado dentro de uma função membro de MyClass , é possível que você está excluindo (por alguma razão) a MyClass instância que possui o _transactions você está iteração?

Neste caso, você pode obter um erro em isso ++ instrução dentro do para desde o este objeto não existe mais. (Naturalmente, o erro poderia ser em outro lugar também, como na própria exclusão.)

Certifique-se chamar _transactions.clear () após o loop for.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top