wifstream crashes the program

This is a discussion on wifstream crashes the program within the C++ Programming forums, part of the General Programming Boards category; I am having problem to write a wstring to a file. I have made functions to write and read strings ...

The program gets compiled without problems with Borland C++ compiler 5.5.1 but if I run the program, I get the text "Abnormal program termination". The first time I run the program (and the first time after restarting the computer) Windows gives me the message that there is not enough virtual memory available.

I don't think that's a good idea.
wchar_t is 2 bytes, and you pass in a buffer size of 4 bytes! So the actual buffer length is actually 8 bytes, more than the number of bytes occupied by your integer.
That means you're writing the len value + 4 undefined bytes which you read back later and get an undefined size.

I don't think that's a good idea.
wchar_t is TWO bytes, and you pass in a buffer size of 4 bytes!
That means you're writing the len value + 2 undefined bytes which you read back later and get an undefined size.

??
Think about it again. The cast is only there because write just wants a char* / wchar_t*.
Kurt

He's not writing a wchar_t. He's casting it to a wchar_t *. That could very well still be 4 bytes on a 32-bit machine. It's still wrong, of course.

Edit: Actually no, I don't think it's wrong per se. Just convoluted because of how the write() function is. To make it better perhaps he should be writing sizeof() with the variable name instead of the type (ie. sizeof(len) vs sizeof(int). That might help make it a little more obvious.

Unless write() casts that wchar_t* to a char* internally, it will write 4 more bytes than it should. Thus an undefined value is written and read back.
Since wchar_t is two bytes, the buffer size is supposed to be 2. The first element gets bytes 1 & 2 and writes them successfully to the buffer. The second takes 3 & 4 and does the same.
But wait... an int is only 4 bytes! So when the loop comes on the 3rd (bytes 5 & 6) and 4th (bytes 7 & 8) run, it will read junk and store into the buffer.

Maybe it is because of my bad English but I don't still understand how I must solve the problem and I don't understand the problem itself very well (why does the write function for the normal string work after looking on what you have wrote). I also don't understand what your doing in the second for-statement.

> wchar_t *str_w = new wchar_t[len];
> wfin.read(str_w, len);
> std::wstring w = str_w;
> delete str_w;
1. does len represent the number of bytes (which read will need), or the number of wchar's (which new will need) ?
2. The assignment will fail, because there is no \0 at the end. That is, unless you always write a \0 and include that in your count when you write the file.
3. The delete needs to be delete [ ] str_w. If you use [ ] on the new, then you must use [ ] on the delete.

The write function writes the number of elements that you specify in the size parameter.
Thus, it writes index 0, 1, 2 and 3. Bytes 1 & 2, 3 & 4, 5 & 6, 7 & 8. But an int is only 4 bytes long, so the range bytes 5-8 is not part of your int and is something else.

1. len is the number of wchar's. I have replaced wfin.read(str_w, len) by wfin.read(str_w, len*sizeof(wchar_t)); and the same for wfout.read(...);
2. This will not fail because there is a statement len++ for the '\0';
3. Your right that I have forgotten [] on the delete.

1. len is the number of wchar's. I have replaced wfin.read(str_w, len) by wfin.read(str_w, len*sizeof(wchar_t)); and the same for wfout.read(...);

This is not right.
It should be:

Code:

wfin.read(str_w, len) by wfin.read(str_w, len / sizeof(wchar_t));

For both read and write. Think a moment what you're doing.

sizeof(int) is presumably 4 bytes (it is on 32-bit system), so let's assume it's 4 bytes. Then you do * sizeof(wchar_t) which is 2, that makes it 8! And then the write tries to write 8 indexes, thus writing 8 * 2 = 16 bytes. That's a lot more than those 4 bytes of your len variable.