Para mi esta mal planteado de base, no podes escribir un std::string asi en un archivo, estas usando los datos de la representacion interna del objeto. Deberias usar la cadena devuelta por c_str. ¿Como sabes el tamaño de un std::string en primer lugar (sizeof(registro) lo asume implicitamente como fijo)? ¿Que pasa si la cadena no es trivial y el std::string usa memoria dinamica?
Ejemplo (VC++ 2017 x64):
std::string test = "creo que esta cadena es lo suficientemente larga como para que la clase std::string tenga que guardarla en memoria dinamica";
Ahora el viejo y querido WinDbg:
0:000> x
000000d5`ca5afe20 test = "creo que esta cadena es lo suficientemente larga como para que la clase std::string tenga que guardarla en memoria dinamica"
0:000> db 000000d5`ca5afe20
000000d5`ca5afe20 b0 c8 52 38 93 02 00 00-15 48 7c f8 f6 7f 00 00 ..R8.....H|.....
000000d5`ca5afe30 7b 00 00 00 00 00 00 00-7f 00 00 00 00 00 00 00 {...............
000000d5`ca5afe40 d8 4b 90 46 a8 84 00 00-88 7b 84 f8 f6 7f 00 00 .K.F.....{......
000000d5`ca5afe50 00 00 00 00 00 00 00 00-34 4d 7c f8 f6 7f 00 00 ........4M|.....
000000d5`ca5afe60 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afe70 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afe80 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afe90 00 00 00 00 00 00 00 00-24 7c 59 ac fc 7f 00 00 ........$|Y.....
0:000> db
000000d5`ca5afea0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afeb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afec0 00 00 00 00 00 00 00 00-a1 ce ea ac fc 7f 00 00 ................
000000d5`ca5afed0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afee0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afef0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5aff00 00 00 00 00 0b 0c d3 86-00 00 00 00 00 00 00 00 ................
000000d5`ca5aff10 00 00 00 00 00 00 00 00-90 0f 17 aa fc 7f 00 00 ................
0:000> db
000000d5`ca5aff20 c0 ee 5a ca d5 00 00 00-80 98 85 ff 0f 00 60 73 ..Z...........`s
000000d5`ca5aff30 9b 03 c4 2c fc 7f 00 00-c0 ee 5a ca d5 00 00 00 ...,......Z.....
000000d5`ca5aff40 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5aff50 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5aff60 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5aff70 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5aff80 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5aff90 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0:000> db
000000d5`ca5affa0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5affb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5affc0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5affd0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5affe0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5afff0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
000000d5`ca5b0000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
000000d5`ca5b0010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
Eso se escribiria usando la logica de estos programas, ahi no esta la cadena en cuestion sin un puntero a la misma y otros campos del std::string.
Como se puede ver aca esto funcionaria (dada la implementacion que estoy usando de la STL que puede cambiar sin que lo sepamos con cualquier actualizacion) de casualidad mientras la cadena tuviera pocos caracteres (15 o menos) y se usara _Buf en lugar de _Ptr.
0:000> dq 000000d5`ca5afe20
000000d5`ca5afe20
00000293`3852c8b00:000> da 00000293`3852c8b0
00000293`3852c8b0 "creo que esta cadena es lo sufic"
00000293`3852c8d0 "ientemente larga como para que l"
00000293`3852c8f0 "a clase std::string tenga que gu"
00000293`3852c910 "ardarla en memoria dinamica"
Deberias definir un formato POD para poder leer y escribir.
https://en.wikipedia.org/wiki/Passive_data_structurehttps://en.wikipedia.org/wiki/SerializationTambien al llamar a fread estamos nuevamente escribiendo en donde no deberiamos, la estructura interna del std::string, en unos objetos que ya llamaron a su constructor. ¿Que pasa si le escribimos en _Ptr un puntero indefinido? A la larga nada bueno y esto es un std::string si llegamos a hacerlo con otros contenedores con representacion interna mas compleja pueden haber mas problemas.
En mi caso sucede esto al llamar al destructor, se intenta liberar un puntero erroneo y corrompe el monticulo:
0:000> g
(c814.e2f8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
ntdll!RtlpFreeHeapInternal+0x7d3:
00007ffc`ace807e3 41807d0f05 cmp byte ptr [r13+0Fh],5 ds:00000232`9c5da59f=??
0:000> k
# Child-SP RetAddr Call Site
00 00000023`eb94fbf0 00007ffc`ace7fba1 ntdll!RtlpFreeHeapInternal+0x7d3
01 00000023`eb94fca0 00007ff7`548136dc ntdll!RtlFreeHeap+0x51
02 00000023`eb94fce0 00007ff7`547808f7 swrite!_free_base+0x1c [minkernel\crts\ucrt\src\appcrt\heap\free_base.cpp @ 105]
03 00000023`eb94fd10 00007ff7`5478b9a2 swrite!std::_Deallocate<16,0>+0x37 [c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xmemory0 @ 208]
04 00000023`eb94fd40 00007ff7`54786217 swrite!std::allocator<char>::deallocate+0x22 [c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xmemory0 @ 993]
05 00000023`eb94fd70 00007ff7`54783bb3 swrite!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Tidy_deallocate+0x87 [c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xstring @ 3995]
06 00000023`eb94fdc0 00007ff7`5478bd9d swrite!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_string<char,std::char_traits<char>,std::allocator<char> >+0x13 [c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xstring @ 2461]
07 00000023`eb94fdf0 00007ff7`547c4d34 swrite!main+0x7d [c:\src\swrite.cpp @ 30]
08 (Inline Function) --------`-------- swrite!invoke_main+0x22 [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 78]
09 00000023`eb94fe60 00007ffc`ac597c24 swrite!__scrt_common_main_seh+0x10c [d:\agent\_work\2\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288]
0a 00000023`eb94fea0 00007ffc`aceacea1 KERNEL32!BaseThreadInitThunk+0x14
0b 00000023`eb94fed0 00000000`00000000 ntdll!RtlUserThreadStart+0x21
PD. El operador == de std::string llama a std::string::compare que es
case sensitive.