Can anyone explain to me this "Access violation writing location 0xDDDDDDDD" i get

-1
#include <iostream>
#include <string>
#include <fstream>
#include <map>

void Find(std::multimap<char, int>& multimap, char c)
{
    if (multimap.find(c) != multimap.end()) { std::cout << multimap.find(c)->second << '\n'; }
    else std::cout << "Not Found" << '\n';
}

int main()
{
    std::multimap<char, int> Componentes;
    std::multimap<char, int>::iterator it;

    for (int i = 0; i < 3; i++)
    {
        Componentes.insert(std::pair<char, int>('a' + i, 1 + i));
    }

    std::fstream MyFile;

    MyFile.open("MyFile.bin", std::fstream::out | std::fstream::in | std::fstream::binary | std::fstream::trunc);

    if (MyFile.is_open())
    {
        MyFile.write(reinterpret_cast <char*> (&Componentes), sizeof(Componentes));
        MyFile.close();
    }

    std::multimap<char, int> Componentes_from_file;
    std::multimap<char, int>::iterator it1;

    MyFile.open("MyFile.bin", std::fstream::in | std::fstream::binary);

    if (MyFile.is_open())
    {
        MyFile.read(reinterpret_cast <char*> (&Componentes_from_file), sizeof(Componentes)); 
        MyFile.close();
    }

    for (it1 = Componentes_from_file.begin(); it1 != Componentes_from_file.end(); it1++)
    {
        std::cout << "Name: " << it1->first << " Number: " << it1->second << std::endl;
    }

    char find;
    std::cout << "Insira char a procurar:";
    std::cout << '\n';
    std::cin >> find;

    Find(Componentes_from_file, find);

    std::cin.get();
} 

At the end of compilation I get an error: "Exception thrown at 0x0006E282 in Ex3.exe: 0xC0000005: Access violation writing location 0xDDDDDDDD.", and I don't really get why that is. I tried passing by reference and passing a pointer to the multimap with the same result.

It sends me to thsi section on xmemory.h (I think)

// MEMBER FUNCTIONS FOR _Container_base12
inline void _Container_base12::_Orphan_all() noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
    if (_Myproxy) { // proxy allocated, drain it
        _Lockit _Lock(_LOCK_DEBUG);

        for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
            (*_Pnext)->_Myproxy = nullptr;
        }

        _Myproxy->_Myfirstiter = nullptr;
    }
#endif // _ITERATOR_DEBUG_LEVEL == 2
c++
asked on Stack Overflow Aug 31, 2020 by André Costa • edited Aug 31, 2020 by André Costa

3 Answers

2
MyFile.write(reinterpret_cast <char*> (&Componentes), sizeof(Componentes));

And

MyFile.read(reinterpret_cast <char*> (&Componentes_from_file), sizeof(Componentes));

You can't just pretend like they're char* and write/read them like that.

answered on Stack Overflow Aug 31, 2020 by Hatted Rooster
2

What happens here is clearly described in documentation of std::is_trivially_copyable:

Objects of trivially-copyable types that are not potentially-overlapping subobjects are the only C++ objects that may be safely copied with std::memcpy or serialized to/from binary files with std::ofstream::write()/std::ifstream::read().

emphasis is mine. It is pretty clear that std::multimap is not trivially copyable.

Here you can find requirements for a class to be trivially copyable. If it is not obvious you can assume that object is not trivially copyable unless specified otherwise as it is a pretty strict requirement. As much as I am aware none of the standard containers except probably std::array are trivially copyable.

answered on Stack Overflow Aug 31, 2020 by Slava • edited Aug 31, 2020 by Slava
0
#include<iostream>
#include<fstream>
#include <string>
#include <map>



void writeFile(std::string filename, std::multimap<std::string, int> mapComp) 
{
    std::ofstream myFile;
    myFile.open(filename, std::ios::out | std::ios::binary | std::ios::trunc);

    if (myFile.is_open())
    {
        myFile << mapComp.size() << std::endl;
        for (auto i : mapComp) {
            myFile << i.first << std::endl;
            myFile << i.second << std::endl;
        }
    }

    myFile.close();   
    std::cout << "File saved and closed succesfully." << std::endl;
}

std::multimap<std::string, int> readFile(std::string filename) 
{

    std::multimap<std::string, int> mapComp;
    std::ifstream myFile;

    myFile.open(filename, std::ios::in | std::ios::binary);

    if (myFile.is_open())
    {
        int size;
        myFile >> size;

        for (int i = 0; i < size * 2; i = i + 2) {
            std::string name;
            int quantity;
            myFile >> name >> quantity;
            mapComp.insert(std::make_pair(name, quantity));
        }
    }

    myFile.close();
    return mapComp;
}

void Print(std::multimap<std::string, int> mapCompCopy)
{
    for (auto i : mapCompCopy) 
    {
        std::cout << "Name: " << i.first << " Number: " << i.second << std::endl;
    }
}

int main() {

    std::multimap<std::string, int> mapComp;
    std::multimap<std::string, int> mapCompCopy;

    mapComp.insert(std::make_pair("Resistor", 2));
    mapComp.insert(std::make_pair("Capacitor", 6));
    mapComp.insert(std::make_pair("AmpOp", 32));

    writeFile("Myfile.bin", mapComp);
    mapCompCopy = readFile("Myfile.bin");
    Print(mapCompCopy);

    std::cin.get();
}

This was working for me.

answered on Stack Overflow Aug 31, 2020 by André Costa

User contributions licensed under CC BY-SA 3.0