2

I hope the title was good enough to help explain what I am having problems with. I think once I solve this problem my project will be pretty much finished. Just a note, both projects are compiled under Unicode.

I am working with a CLI/C++ DLL that takes in a LPCTSTR and returns a const char*. If I store the value of the return in a const char* in my project while stepping through I can see the value its returning is what I expect to be returned.

Now if I do the following:

LPCTSTR strValue = L"test";
const char* Return = MethodCall(strValue);
LPCTSTR Final = CString(Return);

Return will equal "Xmkk=Asmks" (which is what it should). This method encrypts a string. The problem is when I do CString, Final will equal "ﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮ㹙癞鞮᠀諸²⤐²". How do I turn the onst char* into a LPCTSTR without changing its data"

Thank you.

Landin Martens
  • 3,283
  • 12
  • 43
  • 61

3 Answers3

4

After CString(Return) is destructed (this happens "right on next line after its construction") "Final" pointer is pointing to dealocated chunk of memory (which was internal CString(Return) buffer). At this point contents of memory to which it points is undefined and dereferencing it is undefined behaviour.
To use pointer to internal buffer safelly you should ensure that CString which owns buffer is alive as long as pointer is.


LPCTSTR strValue = L"test";
const char* Return = MethodCall(strValue);
LPCTSTR PointerToBuffer= 0;
{
  CString ReturnStringObj(Return);
  PointerToBuffer = ReturnStringObj;  
  // Can safelly use your pointer here  
}
// Here ReturnStringObj is killed and pointer dereferencing is invalid here




cybevnm
  • 2,586
  • 4
  • 30
  • 33
  • The method returns "Final", so what would I do to fix my problem. I am still learning. – Landin Martens Mar 20 '12 at 17:27
  • @user1078510: maybe `LPCTSTR Final = _tcsdup(CString(Return));`. Don't forget to `free(Final)` at some point. – Michael Burr Mar 20 '12 at 17:34
  • It depends... How long Return pointer will point to valid memory after MethodCall etc. You can just store whole CString somewhere (as member of class etc.), or you can use std::wstring. It depends mainly on your design – cybevnm Mar 20 '12 at 17:35
1

As vnm mentions, you're creating a temporary CString object by calling its constructor in line 3, and then that object gets immediately destroyed. This deallocates the chunk of memory it was using for your buffer, meaning that any attempts to access the data stored in that memory would be undefined behavior. That's why your string looks garbled: it's already been deleted.

If you're new to C++, you need to make sure that you understand object lifetimes. That would make writing this code significantly simpler.

The solution is to ensure that your CString object does not get destroyed until you're finished with it. If you only need the object to exist within your function, you can leave it as a temporary object created inside of that function. If you need it to exist outside of that function, you'll need to create it at a higher level or save a pointer to it.

Note that CString objects are implicitly convertible to a LPCTSTR.

So assuming that you only need the CString object to stay alive within the scope of your function, you could write the following code:

{
    // Declare a string literal
    LPCTSTR strValue = L"test";

    // Encrypt the string
    const char* strReturn = MethodCall(strValue);

    // Create a CString object representing the encrypted string
    CStringA myString(strReturn);

    // Do something with myString, like display it in a message box
    // (Remember that it's an ANSI (non-Unicode) string!)
    // ...
    MessageBoxA(NULL, myString, NULL, MB_OK);
    // ...

    // myString (your CString object) gets destroyed here
}
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
0

What you can do is create a new CStringA object and cast this to const char* for Final. Then Final will remain valid as long as the CStringA is defined.

I'd recommend against using a CString (or CStringW) for storage that you will need to access using const char*.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150