二进制读/写中的SIGABRT
SIGABRT in binary read/write
我写了一个非常小的代码片段,已经得到了以下错误:
malloc: *** error for object 0x100100080: pointer being freed was not allocated
问题是,我不知道编译器在说什么指针。我通过地址将一个变量传递给读/写函数,但据我所知,我从未释放过它。我的代码中的错误在哪里?我和Leaks和Zombies合作过,但一无所获。
这是我的程序:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Bank
{
private:
string __name;
public:
Bank()
{
__name = "";
}
Bank(string name)
{
__name = name;
}
string getName() const { return __name; }
};
int main (int argc, char * const argv[])
{
Bank bank("Bank of America");
Bank bank2;
cout << "Bank1: " << bank.getName() << endl;
string filename = bank.getName() + ".bank";
ofstream fout(filename.c_str(), ios::binary);
if (fout.good())
fout.write((char *)&bank, sizeof(bank));
fout.close();
ifstream fin(filename.c_str(), ios::binary);
if (fin.good())
fin.read((char *)&bank2, sizeof(bank2));
fin.close();
cout << "Bank2: " << bank2.getName() << endl;
return 0;
}
使用fin.read()--无法读取包含std::字符串(或任何非纯Ol数据的对象)的对象
对象是以字节流的形式读取和写入的,但std:string包含一个指向存储在其他地方的内存的指针,该指针不是用fout.write()写入的,也不是用fin.read()正确初始化的
这是因为它没有用fin.read()正确初始化,所以您得到了堆错误;当对象超出范围时,会调用初始化不正确的std::string的析构函数,并试图释放它不拥有的内存。
您可能想要为对象编写一个自定义的i/o方法,并逐个保存或加载它。要获得执行此操作的快捷方式,请使用Boost序列化库。
因为您的Bank类包含std::字符串,所以您不能像您所想的那样将其读/写为二进制。std::字符串具有内部指针。如果你把它写成二进制,你只会写指针,而不是实际的字符串内容。同样,当你读取字符串时,你将读取一个指针。在这种情况下,您最终会使bank和bank2对象都有指向同一内存的字符串,因此当该内存被释放时,它会被释放两次。
你需要用其他方式将你的银行数据写入文件。在这种情况下,一个带有银行名称的简单ASCII文件就可以了。
你不能做你正在做的事情,因为std::string
不能像那样复制。在内部,string
对象分配内存,而外部结构的简单副本并不能达到预期效果。
您需要正确地序列化此结构。
- 请不要使用下划线
- 参照传递对象:
Bank(string& name)
- 这是邪恶的:
fout.write((char *)&bank, sizeof(bank));
- 您可能想要在
Bank
类的ostream操作符中编写<<
和>>
例如:
friend std::ostream& operator<<(std::ostream &out, const Bank& b);
friend std::istream& operator>>(std::istream &out, const Bank& b);
ostream的成员函数write和istream的Members函数read专门设计用于输入和输出二进制数据。如果您确实想操作二进制数据,请使用以下方法:
ifstream fin(filename.c_str(), ios::in|ios::binary|ios::ate);
size = fin.tellg();
memblock = new char [size];
fin.seekg(0, ios::beg);
if (fin.good()){
fin.read(memblock, size);
fin.close();
}
delete[] memblock;
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 有根的二进制搜索树.保留与其父级的链接
- 多态二进制函数
- 正在读取二进制文件(is_open)
- visual在c++中将十进制数转换为二进制数
- C++十进制到二进制,如何转换
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- 二进制搜索树叶数问题
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 为什么二进制搜索在我的测试中不起作用
- 重载==不适用于二进制树
- 正在尝试重载二进制搜索树分配运算符
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 带有数组键C++的二进制映射
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 二进制数之和(使用C样式字符串)
- 如何从dicom文件中读取二进制数据
- 二进制读/写中的SIGABRT