views:

124

answers:

2

I am writing two lines in memory using CMemFile::Write():

void CLISTCTRLDlg::Export(LPTSTR *pBlock)
{
 CMemFile outMem(32768);

 CString csHeader = _T("EmpId EmpName EmpAddress\n");
 outMem.Write(csHeader.GetBuffer(0), csHeader.GetLength());

 CString csInfo = _T("1 TestName TestAddress\n");
 outMem.Write(csInfo.GetBuffer(0), csInfo.GetLength());

 long lLen = outMem.GetLength() + 1;
 BYTE *mBlock = outMem.Detach();
 *pBlock = (LPTSTR) malloc(sizeof(char) * lLen);
 memcpy(*pBlock, mBlock, lLen-1);
 (*pBlock)[lLen -1] = 0;
 OutputDebugStringW(*pBlock);
 free(outMem);
}

The output window shows the string "EmpId EmpNam? ???????? ?????????" when the OutputDebugStringW(*pBlock); statement is executed.

I do not understand why the data is truncated.

Further more, the system throws an unhandled exception when the statement free(outMem); is executed.

Can anyone please guide me to the solution and let me know where I am mistaken?

Thanks.

A: 

No need to complicate things, to store:

CMemFile file;
CArchive archive(&file, CArchive::store);

CString csHeader = _T("EmpId EmpName EmpAddress\n");
archive << csHeader;

CString csInfo = _T("1 TestName TestAddress\n");
archve << csInfo;

archive.Close();

To load:

file.Seek(0, 0); // rewind the file
CArchive archive(&file, CArchive::load);

CString temp;
archive >> temp;

No need to use memcpy or fiddle with memory.

Nikola Smiljanić
A: 
*pBlock = (LPTSTR) malloc(sizeof(char) * lLen);
memcpy(*pBlock, mBlock, lLen-1);

You appear to be working with wide-character strings everywhere else, but these two calls deal with bytes. They should be:

 *pBlock = (LPTSTR) malloc(sizeof(TCHAR) * lLen);
 memcpy(*pBlock, mBlock, sizeof(TCHAR) * (lLen-1));

...though as Nikola notes, you're better off if you avoid C-style memory and string manipulation entirely.

Edit: As for the exception when executing free(outMem);... I'm not sure why that even compiles - outMem is your CMemFile object, which is stack-allocated and not a pointer. You should be doing:

free(mBlock); // release memory allocated by, but now detached from CMemFile
Shog9
I tried it but got the same exception.
I believe that is because because `(*pBlock)[lLen -1] = 0;` also needs to be updated to handle tchar size offset `(*pBlock)[lLen*sizeof(TCHAR)] = 0;`
Ruddy
@Ruddy: I don't think so... `pBlock` is of type `TCHAR**`, so an index applied to `(*bBlock)` will be an index into an array of `TCHAR`s. Note that if it was actually a byte array, you'd need to cast it to a TCHAR array first anyway in order to set a double-byte NULL terminator! @unknown: I missed this last night, but... You're `free()`ing the wrong object! See my edit...
Shog9
Ruddy