简体   繁体   中英

How am I getting a read access violation thrown with unordered_map .find()?

After stepping through many times with my debugger, I still cannot figure out how I am getting a read access violation. I have a std::unordered_map<std::string, int> with 8 pairs stored at the time of error. The faulty line of code reads as follows:

auto it = this->mapRegisters.find(param);

Where :
string param = "3";
this->mapRegisters = std::unordered_map<std::string, int> has 8 values in it:

{  
 ("R0", 0),  
 ("R1", 1),  
 ("R2", 2),  
 ("R3", 3),  
 ("R4", 4),  
 ("R5", 5),  
 ("R6", 6),  
 ("R7", 7),  
}  

this is obviously not the correct syntax, just a way of showing you the information
Call Stack

>   VirtualMachine.exe!std::_Iterator_base12::_Adopt(const std::_Container_base12 * _Parent) Line 1160  C++
    VirtualMachine.exe!std::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>>>,std::_Iterator_base12>::_List_unchecked_const_iterator<std::_List_val<std::_List_simple_types<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>>>,std::_Iterator_base12>(std::_List_node<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>,void *> * _Pnode, const std::_List_val<std::_List_simple_types<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>>> * _Plist) Line 41   C++
    VirtualMachine.exe!std::_List_const_iterator<std::_List_val<std::_List_simple_types<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>>>>::_List_const_iterator<std::_List_val<std::_List_simple_types<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>>>>(std::_List_node<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>,void *> *)  C++
    VirtualMachine.exe!std::list<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>,std::allocator<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>>>::_Make_const_iter(std::_List_node<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>,void *> * _Where) Line 1128    C++
    VirtualMachine.exe!std::_Hash<std::_Umap_traits<std::string,enum VirtualMachine::RegisterLoc,std::_Uhash_compare<std::string,std::hash<std::string>,std::equal_to<std::string>>,std::allocator<std::pair<std::string const ,enum VirtualMachine::RegisterLoc>>,0>>::find<void>(const std::string & _Keyval) Line 1334   C++
    VirtualMachine.exe!VirtualMachine::getParamVal(std::string param, std::unordered_map<std::string,int,std::hash<std::string>,std::equal_to<std::string>,std::allocator<std::pair<std::string const ,int>>> & symTable) Line 166  C++
    VirtualMachine.exe!VirtualMachine::secondPass(std::basic_ifstream<char,std::char_traits<char>> & inFS, std::unordered_map<std::string,int,std::hash<std::string>,std::equal_to<std::string>,std::allocator<std::pair<std::string const ,int>>> & symTable) Line 94  C++
    VirtualMachine.exe!VirtualMachine::parseAssemblyFile(std::string filename) Line 30  C++
    VirtualMachine.exe!main(char * argv, int argc) Line 7   C++

This line is within a function that is called and ran several times before this point successfully.

After stepping through all of my allocations, I recognized that one of them was not large enough for what I was using it for elsewhere in the program. This was causing the program to read and write to a location that it did not have access to. While this would not necessarily affect the map and .find() function mentioned, that is where the program would crash probably from accessing one of those stored parameters.

I think i found a decent solution. You could possibly encapsulate an unordered_map in a class and use its distructor to raise a flag and detect it as an edge case in the destructor of the object that is typaram in the hash table. Like this:

template<typename K, typename V>
struct hash_table
{
    unordered_map<K, V> map;
    bool is_being_deleted = false;
    ~hash_table()
    {
        is_being_deleted = true;
    }
};

struct PageRefrence
{
    string str;
    int page;
    hash_table<string, PageRefrence>& refTable;
    ~PageRefrence()
    {
        if (refTable.is_being_deleted == true) // When the map is in the procces of deletion
            return;
        else
        { // Normal case
            auto x = refTable.map.find(str);
            cout << (*x).second.page;
        }

    }
};

int main()
{
    hash_table<string, PageRefrence> refTable;
    refTable.map.insert({ "HELP",{"HELP",42,refTable} });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM