C++ 删除xmemory0中的HashMap元素时出错

C++ 删除xmemory0中的HashMap元素时出错,c++,pointers,hashmap,destructor,C++,Pointers,Hashmap,Destructor,每当我试图删除一个元素,我的HashMap,我得到一个错误,在C++代码不是我的代码…C++的人的代码-具体地,xMeMeNy0。我确信错误在我这边,但我不知道在哪里,因为调试器告诉我它在别处。我的HashMap已经过全面测试,除了尝试删除HashElement时,它似乎运行良好。我非常确定,在我删除HashElement之前,没有任何东西指向它,我认为这是第一个猜测。有人能告诉我为什么在尝试删除HashElement时出错吗?这是我的堆栈跟踪: msvcr120d.dll!operat

每当我试图删除一个元素,我的HashMap,我得到一个错误,在C++代码不是我的代码…C++的人的代码-具体地,xMeMeNy0。我确信错误在我这边,但我不知道在哪里,因为调试器告诉我它在别处。我的HashMap已经过全面测试,除了尝试删除HashElement时,它似乎运行良好。我非常确定,在我删除HashElement之前,没有任何东西指向它,我认为这是第一个猜测。有人能告诉我为什么在尝试删除HashElement时出错吗?这是我的堆栈跟踪:

    msvcr120d.dll!operator delete(void *)   Unknown
>   MyProgram.exe!std::allocator<char>::deallocate(char * _Ptr, unsigned int __formal) Line 573 C++
    MyProgram.exe!std::_Wrap_alloc<std::allocator<char> >::deallocate(char * _Ptr, unsigned int _Count) Line 859    C++
    MyProgram.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Tidy(bool _Built, unsigned int _Newsize) Line 2284 C++
    MyProgram.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >() Line 992 C++
    MyProgram.exe!HashElement::~HashElement() Line 12   C++
我也很乐意发布HashMap本身,但我认为错误与实际的HashMap代码无关,因此我暂时不发布它,以使本文更具可读性

编辑:

刚刚发现这个bug确实存在于我的HashMap中。但不知道在哪里。我这样想是因为简单地创建和删除HashElement并没有重现错误。但代码如下:

HashMap.h

HashMap.cpp


我得到了外界的帮助,然后在评论中得到了@leewangzhong的帮助。问题出在HashMap.cpp的Remove方法中。我确实有一个悬空的指针。以下是正确的方法:

void HashMap::Remove(int key){
    if (!Contains(key)){
        return;
    }
    int hash = GetHash(key);
    HashElement *currentElement = map_[hash];
    if (currentElement->GetKey() == key){
        delete currentElement;
        map_[hash] = nullptr;
    }
    else{
        HashElement *previousElement = currentElement;
        currentElement = currentElement->next_element_;
        while (currentElement->GetKey() != key){
            previousElement = currentElement;
            currentElement = currentElement->next_element_;
        }
        previousElement->next_element_ = currentElement->next_element_;
        delete currentElement;
    }
    count_--;
}

这是一个真正的项目还是家庭作业?因为你应该使用向量和智能指针,而不是new/delete,我敢打赌这些问题很快就会消失。这是一个投资组合。我故意不使用智能指针。如果它是真实的东西,我会这么做:-我不知道公文包是什么意思。注释更正:您应该学习初始化列表、常量成员函数和通过常量引用传递字符串。@NeilKirk谢谢您的建议。我会把它作为我的下一个冒险你仍然会有一个悬而未决的指针。删除对if currentElement->next\u element\u的检查,这样如果它为null,则previousElement->next\u element\u将正确设置为null。此外,您在表中执行两个搜索:一个用于包含,另一个用于删除。如果你为它不包含元素的可能性做准备,就不需要寻找遏制。如果在链的最后一个元素中找到了密钥,是否需要检查?如果在链子的末尾找到了密钥,请考虑在预存中发生了什么。但是当函数返回时,它对当前代码的值是多少?curr没有next意味着什么?这意味着currentElement->next_Element_uu为空。移除链的最后一个元素意味着什么?这意味着prev现在没有下一个。对于您当前的代码,prev仍然认为curr是它的下一个代码。经验法则:如果你删除了某个东西,你应该考虑是否需要将其置空。
#include "HashElement.h"

HashElement::HashElement(int key, std::string value)
{
    key_ = key;
    value_ = value;
    next_element_ = nullptr;
}

HashElement::~HashElement()
{
}  //This is the last line before it goes off into not my code

int HashElement::GetKey(){
    return key_;
}

std::string HashElement::GetValue(){
    return value_;
}
#pragma once
#include <string>

#include "HashElement.h"

class HashMap
{
private:
    HashElement **map_;
    int size_;
    int count_;
public:
    HashMap(int);
    ~HashMap();
    int GetHash(int);
    void Put(int, std::string);
    std::string GetElement(int);
    bool Contains(int);
    void Remove(int);
    int GetCount();
};
#include "HashMap.h"

HashMap::HashMap(int size)
{
    size_ = size;
    map_ = new HashElement*[size_]();
}

HashMap::~HashMap()
{
    for (int i = 0; i < size_; i++){
        int hash = GetHash(i);
        if (!map_[hash]){
            continue;
        }
        HashElement *currentElement = map_[hash];
        HashElement *nextElement = map_[hash];
        while (nextElement->next_element_){
            nextElement = nextElement->next_element_;
            delete currentElement;
            currentElement = nextElement;
        }
        delete currentElement;
    }
}

int HashMap::GetHash(int key){
    return key % size_;
}

void HashMap::Put(int key, std::string value){
    int hash = GetHash(key);
    if (!map_[hash]){
        map_[hash] = new HashElement(key, value);
    }
    else{
        HashElement *lastElement = map_[hash];
        while (lastElement->next_element_){
            lastElement = lastElement->next_element_;
        }
        lastElement->next_element_ = new HashElement(key, value);
    }
    count_++;
}

std::string HashMap::GetElement(int key){
    int hash = GetHash(key);
    if (map_[hash]){
        HashElement *currentElement = map_[hash];
        while (currentElement->GetKey() != key && currentElement->next_element_){
            currentElement = currentElement->next_element_;
        }
        return currentElement->GetValue();
    }
    return nullptr;
}

bool HashMap::Contains(int key){
    int hash = GetHash(key);
    if (map_[hash]){
        HashElement *currentElement = map_[hash];
        while (currentElement->GetKey() != key && currentElement->next_element_){
            currentElement = currentElement->next_element_;
        }
        if (currentElement->GetKey() == key){
            return true;
        }
    }
    return false;
}

void HashMap::Remove(int key){
    if (!Contains(key)){
        return;
    }
    int hash = GetHash(key);
    HashElement *currentElement = map_[hash];
    if (!currentElement->GetKey() == key){
        HashElement *previousElement = currentElement;
        currentElement = currentElement->next_element_;
        while (currentElement->GetKey() != key){
            previousElement = currentElement;
            currentElement = currentElement->next_element_;
        }
        if (currentElement->next_element_){
            previousElement->next_element_ = currentElement->next_element_;
        }
    }
    delete currentElement;
    count_--;
}

int HashMap::GetCount(){
    return count_;
}
void HashMap::Remove(int key){
    if (!Contains(key)){
        return;
    }
    int hash = GetHash(key);
    HashElement *currentElement = map_[hash];
    if (currentElement->GetKey() == key){
        delete currentElement;
        map_[hash] = nullptr;
    }
    else{
        HashElement *previousElement = currentElement;
        currentElement = currentElement->next_element_;
        while (currentElement->GetKey() != key){
            previousElement = currentElement;
            currentElement = currentElement->next_element_;
        }
        previousElement->next_element_ = currentElement->next_element_;
        delete currentElement;
    }
    count_--;
}