wxString pointer crash

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Lowkus
Experienced Solver
Experienced Solver
Posts: 55
Joined: Sun May 01, 2016 2:48 am

wxString pointer crash

Post by Lowkus » Mon Feb 11, 2019 6:41 am

Running wxWidgets-3.1.0.

I'm probably making some basic mistake. Why does this crash at runtime? And why do I get this build warning?
warning: 'sVol' may be used uninitialized in this function.

Code: Select all

wxString* sVol;
*sVol = wxT("hi");
wxMessageBox(*sVol, wxT("caption"));

New Pagodi
Super wx Problem Solver
Super wx Problem Solver
Posts: 283
Joined: Tue Jun 20, 2006 6:47 pm
Contact:

Re: wxString pointer crash

Post by New Pagodi » Mon Feb 11, 2019 8:15 am

Lowkus wrote:

Code: Select all

wxString* sVol;
*sVol = wxT("hi");
wxMessageBox(*sVol, wxT("caption"));

The first line creates a pointer variable but does not initialize it. So it contains a random number.

The second line dereferences the pointer and tries to assign it to the contents of another string. What does that do? See here. The pointer was a random number, so the dereferenced pointer is a random block of memory. As mentioned in that link, the assignment statement will try to use the wxString assignment operator to dump the contents of the string on the right side into that random block of memory. The operating system knows this is a bad thing - that random block of memory could belong to another program or the operating system itseld. So the OS makes the program crash when it tries to do this write.

The best way to do this is to not use pointers at all:

Code: Select all

wxString sVol;
sVol = "hi";
wxMessageBox(sVol, "caption");


You don't need the wxT macro anymore. If you really, really want to use a pointer, do something like this:

Code: Select all

wxString* sVol = new wxString();
*sVol = "hi";
wxMessageBox(*sVol, "caption");
Then later on, be sure to call:

Code: Select all

delete sVol;

Lowkus
Experienced Solver
Experienced Solver
Posts: 55
Joined: Sun May 01, 2016 2:48 am

Re: wxString pointer crash

Post by Lowkus » Mon Feb 11, 2019 8:32 am

That helps immensely, thanks! I normally wouldn't use a pointer but I'm going to pass it into SplitPath and I think that requires a pointer. Here's what it ended up looking like and it seems to work a treat.

Code: Select all

//...earlier code fetched the filepathname...

wxString* sVol = new wxString;
wxString* sDir = new wxString;
wxString* sFilename = new wxString;
wxString* sExt = new wxString;
bool* bHasExt = new bool;

wxFileName::SplitPath(filepathname,
                    sVol,
                    sDir,
                    sFilename,
                    sExt,
                    bHasExt,
                    wxPATH_NATIVE
                    );

wxMessageBox(*sVol, "volume");
wxMessageBox(*sDir, "dir");
wxMessageBox(*sFilename, "filename");
wxMessageBox(*sExt, "ext");
wxMessageBox(*bHasExt ? "true" : "false", "has extension");

User avatar
doublemax
Moderator
Moderator
Posts: 13297
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxString pointer crash

Post by doublemax » Mon Feb 11, 2019 3:53 pm

That's not necessary.

You can do it like this:

Code: Select all

wxString sVol;

wxFileName::SplitPath(filepathname,
                    &sVol,
...
wxMessageBox(sVol, "volume");
The reason why this are pointers is that you can pass a NULL pointer for the values you're not interested in.
Use the source, Luke!

Post Reply