string in structure and fread()

Sam Varshavchik mrsam@courier-mta.com
Sun Dec 25 23:05:00 GMT 2011


Mohsen Pahlevanzadeh writes:

> 	short unsigned size = 100 - strlen((const char *)name.data());

std::string::data() is not guaranteed to be null-terminated. Undefined  
behavior. Furthermore, this is overdoing it. name.size() will work much  
better.

> 	memory = '`';
> 	for (i =0 ;i<size;i++)
> 		memory += '`';
> 	tmp->name = name  + memory;

You should replace all of the above effort with a simple:

tmp->name = name;
tmp->name.resize(100, '`');

>
> 	size = 100 - strlen((const char *)publisher.data());
> 	memory = '`';
> 	for (i =0 ;i<size;i++)
> 		memory += '`';
> 	tmp->publisher =  publisher  + memory;

Same here.

tmp->publisher=publisher;
tmp->publisher.resize(100, '`');

> 	fseek(bookFilePtr,0L,SEEK_END);
> 	fwrite(ptr,408,1,bookFilePtr);

Undefined behavior. std::string is not an char[]. It is a structure.

Hint: if you take a look at what sizeof(ptr) tells you, it's not going to be  
408 bytes.


> 	while ( fread(bookPtrObj,408,1,bookFilePtr) == 1 ){

>
> But i get the segmentation fault on read each field.

fread() and fwrite() read and write a raw char buffer. char[]. std::string  
is not a char[]. Internally, std::string is a single pointer to somewhere  
else in memory, where std::string happens to have dumped the current  
contents of your string. If you fread() and fwrite() the std::string itself,  
fread() and fwrite() knows nothing about what it's reading or writing,  
besides the actual bytes themselves. fread() and fwrite() has no knowledge  
that those bytes consist of a pointer to somewhere else in memory, where a  
string is.

If you actually look at what your fwrite() written out, it's binary garbage.

To do this properly, you have to manually place everything you want to write  
out into a single char buffer. std::vector<char> would be an excellent  
choice:

std::vector<char> buffer;

Then, after you filled this buffer with whatever you want to write:

fwrite(&buffer[0], buffer.size(), 1, fp);

But, if you really want to use C++, rather than C, you should use  
std::ofstream, instead of FILE *.

Then to read what you previous wrote out, you have to allocate the buffer  
first, using resize(), then you can read what you want to read, into the  
newly-allocated buffer.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-help/attachments/20111225/e24b07e7/attachment-0001.sig>


More information about the Gcc-help mailing list