本来想说点什么,没想到楼上的dalao出手这么快,狗尾续貂补点细节吧:
C++标准库的string实现一般来说是Rhyster 的方法,用块动态分配内存解决:
clang的cxx标准库实现(github镜像 commit 7593e799d293c28618fb67b7a2951786dfd18bef)
大概长这样(标准库乃劝退大坑,没事不要乱翻)
struct string {
int string_size;//字符串长度
int buffer_capacity;//内存空间的容量
char* data;//数据本身
//可能的内存分配相关的必要数据......
};
所以,如果写成这样:
int main(){
Cat A("妈妈说名字一定要长长长长,一寸长一寸强",3);
Cat C;
ofstream outfile;
outfile.open("test.txt",ios::out|ios::binary);
outfile.write((char*)&A, sizeof(A));
outfile.close();
ifstream infile;
infile.open("test.txt",ios::in|ios::binary);
infile.read((char*)&C,sizeof(C));
infile.close();
C.print();
}
输出,然后注释掉输出部分,再读,系统就会因为访问未分配内存然后崩溃。
但实际上有些时候标准库会做一个叫”短字符串优化“的操作,如果你的整个字符串比这个struct还小,标准库就会直接把你的字符串存进这个struct里,大概长这样:
typedef string long_version;
struct short_version{
int size;
char values[sizeof(long_version)-sizeof(int)] ;
};
class optimized_string{
private:
union{
long_version l;
short_version s;
}value;
public:
optimized_string(char* val){
if(strlen(val)<*some value*){
//用优化版本
}else{
//用长版本
}
}
};
这时候,如果名字叫“狗蛋”这种很短的字符串的话,标准库就会直接存进去,变成朴素数组,然后IO就能成功。
clang,MSVC,g++,icc,各家编译器的标准库的实现都可能不同,
所以直接存储字符串内存内容这种行为就叫做未定义行为,
标准不关心,程序员也最好不要依赖。