Copy and Store LPTSTR in class causes crash - c++

I am attempting to copy a LPTSTR and store that string as a member variable in an object. But my attempts to copy the LPTSTR seem to fail and when I go to access/print the value of the copied LPTSTR I get a program crash.
Is it possible to copy a LPTSTR and store it in my class below or is it better to just use a TCHAR*?
class Checkbox
{
private:
LPTSTR text;
HWND hwnd;
public:
Checkbox(HWND nHwnd, LPTSTR nText)
{
lstrcpy(checkText, text);
}
void print()
{
// Causes a crash
MessageBox(hwnd, text, text, MB_OK);
}
};

LPTSTR is just a pointer. So, you need to take care to allocate memory before using it. So is the case with TCHAR*. Alternatively you could use wstring, if you have to worry about unicode strings.

You copy to an uninitialized pointer, which will overwrite some random area in memory. You need to allocate memory for the pointer first, and also remember to free the memory when you don't need it anymore.

Like the other answers have said, you need to allocate memory to "LPTSTR text" before you can use it.
Get the length of the string (strlen should do) you want to copy and then allocate the memory like this:
text = TCHAR[length];
You can declare a deconstructor for your class to delete the allocated memory when the program ends or the program leaves the scope of the class instance.
~CheckBox()
{
if (text)
delete[] text;
}
You should also create another constructor with no parameters that sets text to NULL;

Related

C++ function returning BSTR for function that cannot call SysFreeString()

Please bear with me, i have been a c++ programmer for a little while.
I need to know if i am doing this wrong. It works, but i suspect it causes a memory leak. I have this function:
_bstr_t WCH2BSTR(wchar_t* st)
{
BSTR stres = SysAllocString(st);
return (_bstr_t)stres;
}
Let's say i were to use the result like this:
wcout << WCH2BSTR(wCharArr) << " done." << endl;
Will this cause a memory leak, or will the BSTR be deleted by a "garbage collector" like in Java?
If it is a memory leak, how can i prevent it without losing the ability to do it as a one-liner? Sometimes the results of WCH2BSTR are stored in a BSTR variable and disposed of properly, but i would like to use the same function for concatenating wchar_t to BSTR's as well in a one-liner fashion.
Thanks.
You have a memory leak. But it's subtle:
This line:
BSTR stres = SysAllocString(st);
Allocates a BSTR as you expect.
However, the return statement:
return (_bstr_t)stres;
Triggers a call to the _bstr_t(const wchar_t*) constructor, not the which in turn will allocate another BSTR via SysAllocString. So you've leaked a string from the initial call.
This is likely closer to what you want:
_bstr_t WCH2BSTR(const wchar_t* st)
{
return _bstr_t(str);
}
The constructor of _bstr_t will do the SysAllocString thing for you. The destructor of _bstr_t will do the SysFreeString thing for you.
But...
Be careful of saying this:
BSTR bstr = WCH2BSTR(L"Foo");
Because that will compile! But after the assignment to a raw BSTR, the destructor of the _bstr_t returned by the helper function will get invoked and free the already returned pointer.
What you really want to do is to just avoid the helper function altogether and say this explicitly in your code:
_bstr_t bstr = L"Foo";
When the _bstr_t goes out of scope, so does the underlying BSTR that it holds.

How to assign a struct member with a value returned by other function?

I'm trying to make a multithreaded program.
I can compile it successfully, but my program always crashes.
Here is my code snippet :
// in global declaration
typedef struct MyData {
int nSumber;
char *szFileName;
} MYDATA, *PMYDATA;
PMYDATA pData[MAX_THREAD];
// in my OpenDialog function
OPENFILENAME ofn;
char szFile[MAX_PATH];
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
if(GetOpenFileName(&ofn))
// I think this line that makes my program crash
pData[0]->szFileName = ofn.lpstrFile;
Am I doing it wrong?
Thanks in advance!
The pData array contains pointers to MYDATA that are not pointing to valid memory because you haven't allocated any memory yet.
if(GetOpenFileName(&ofn)) {
pData[0] = new MYDATA();
pData[0]->szFileName = ofn.lpstrFile;
}
And now you need to call delete on each allocated pData element to release the memory.
So, instead of going through all that trouble, use an std::vector<MYDATA>.
std::vector<MYDATA> dataVec;
// ...
if(GetOpenFileName(&ofn)) {
MYDATA data;
data.szFileName = ofn.lpstrFile;
data.nSumber = something; // you probably want to init this also
dataVec.push_back(data);
}
I'm not sure about szFileName being a char * and simply pointing it to ofn.lpstrFile. You may need to allocate memory and store the file name in the struct. If that's the case, change szFileName to std::string instead of char *.
Your question leaves out a lot of detail, but if char szFile[MAX_PATH] is local to a function it is on the stack. You can't save it in a global variable and expect it to be used elsewhere because the stack space will be re-used as soon as szFile goes out of scope (at the next } or the end of the function).
For a quick test try ofn.lpstrFile = new char[MAX_PATH] and see if your crash goes away.
This only allocates an array of pointers to the data:
PMYDATA pData[MAX_THREAD];
You need to actually allocate a MYDATA at pData[0] for this to be valid.

Why does MFC C++ CString(const char*) completely changing const char* value?

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.
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
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
}
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*.

How to properly free a std::string from memory

What's the best way to delete an std::string from memory allocated on the heap when I'm done using it? Thanks!
std::string is just a normal class1, so the usual rules apply.
If you allocate std::string objects on the stack, as globals, as class members, ... you don't need to do anything special, when they go out of scope their destructor is called, and it takes care of freeing the memory used for the string automatically.
int MyUselessFunction()
{
std::string mystring="Just a string.";
// ...
return 42;
// no need to do anything, mystring goes out of scope and everything is cleaned up automatically
}
The only case where you have to do something is when you allocate an std::string on the heap using the new operator; in that case, as with any object allocated with new, you have to call delete to free it.
int MyUselessFunction()
{
// for some reason you feel the need to allocate that string on the heap
std::string * mystring= new std::string("Just a string.");
// ...
// deallocate it - notice that in the real world you'd use a smart pointer
delete mystring;
return 42;
}
As implied in the example, in general it's pointless to allocate a std::string on the heap, and, when you need that, still you should encapsulate such pointer in a smart pointer to avoid even risking memory leaks (in case of exceptions, multiple return paths, ...).
Actually std::string is defined as
namespace std
{
typedef std::basic_string<char> string;
};
so it's a synonym for the instantiation of the basic_string template class for characters of type char (this doesn't change anything in the answer, but on SO you must be pedantic even on newbie questions).
std::string foo("since it's on the stack, it will auto delete out of scope");
or:
std::string* foo = new std::string("allocated on the heap needs explicit destruction")
delete foo;
Use delete if it's on the heap, and nothing at all if it's on the stack.
void foo() {
string* myString = new string("heap-allocated objects are deleted on 'delete myString;'");
cout << *myString << endl;
delete myString;
}
or better yet, avoid pointers when possible and use automatic variables:
void foo() {
string myString("stack-allocated string is automatically deleted when myString goes out of scope");
cout << myString << endl;
}
just treat std::string as any basic type.
std::string *str = new std::string("whatever");
///code
delete str;
Maybe your dealing with really freeing the internal string buffer?
For performance reason, most implementation keep the internal buffer allocated, even is the string is "emptied". Additionally: small strings (smaller than sizeof(ptr)) are directly stored in the area that hold pointers. Theses bytes can never be reclaimed during the life of the string.
To free the internals: the classical trick is to use swap within a scope. This force buffer to be really freed (Works also with vector/map/ostream/stringstream etc ...):
string s; // size==0 and capacity==15 as the default proxy of the container (help perf on small string)
s = "Looooooooooooooooooooooooooooooong String"; // size==41 and capacity==47 bytes allocated
s.clear(); // size==0 BUT capacity==47 bytes STILL allocated!!
s = "Looooooooooooooooooooooooooooooong String"; // size==41 and capacity reuse 47 bytes still allocated.
s.resize(0); // size==0 BUT capacity==47 bytes STILL allocated!!
// swap with scope to force freeing string internals
{
string o;
o.swap(s);
} // size==0 AND capacity==15 (back to smallest footprint possible)
s = "12345"; // size==5 AND capacity==15 (the string is IN the container, no new alloc)
You can treat std::string like any other class. Use new for allocation, and delete once you're done with it.
With C++11, I do not recommend usage of new and delete in most cases. If you need to allocate the string on heap, use std::shared_ptr to wrap it:
std::shared_ptr<std::string> my_string = std::make_shared<std::string>(std::string("My string"));
As soon as all the copies of my_string go out of scope, the associated memory is going to be deleted automatically.

When do I need to deallocate memory?

I am using this code inside a class to make a webbrowser control visit a website:
void myClass::visitWeb(const char *url)
{
WCHAR buffer[MAX_LEN];
ZeroMemory(buffer, sizeof(buffer));
MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, url, strlen(url), buffer, sizeof(buffer)-1);
VARIANT vURL;
vURL.vt = VT_BSTR;
vURL.bstrVal = SysAllocString(buffer);
// webbrowser navigate code...
VariantClear(&vURL);
}
I call visitWeb from another void function that gets called on the handlemessage() for the app.
Do I need to do some memory deallocation here?, I see vURL is being deallocated by VariantClear but should I deallocate memory for buffer?
I've been told that in another bool I have in the same app I shouldn't deallocate anything because everything clear out when the bool return true/false, but what happens on this void?
I think you have some fundamental problems with your understanding of memory management. In this case, no, you don't need to explicitly free any memory. You didn't ever call new, so you don't need to call delete. buffer exists only on the stack, and will vanish when this method returns.
If I might, I'd suggest doing this a bit differently -- I'd start by creating a small class:
class bstr {
VARIANT content;
public:
bstr(char const *url) {
WCHAR buffer[MAX_LEN] = {0};
MultiByteToWideChar(CP_ACP,
MB_ERR_INVALID_CHARS,
url,
strlen(url),
buffer,
sizeof(buffer)/sizeof(buffer[0])-1);
content.V_T = VT_BSTR;
content.bstrVal = SysAllocString(buffer);
}
operator VARIANT const &() { return content; }
~bstr() { VariantClear(&content); }
};
Then your code would change to something like:
void myClass::visitWeb(const char *url) {
your_control.Navigate(bstr(url));
}
and all the allocation and freeing gets handled automatically from there.
Even if you don't do use a class like this, note the change to the call to MultiByteToWideChar. The last parameter is supposed to be the number of WCHAR elements in the buffer, not the number of chars. As it is, you've set up a buffer overrun...
I don't see any news, so I wouldn't expect any deletes.
I guess I'd look at the description of SysAllocString() to see if it allocates any memory that you need to get rid of yourself.