#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
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.
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.
#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.
User contributions licensed under CC BY-SA 3.0