Search code examples
c++winapimemoryreferencegetopenfilename

C++ Simple IF clause changes value of a static const char variable


Okay, I've been dealing with this for two days now, and I can't find a solution.

Problem: I'm trying to set a filter to a File Selection Dialog using Winapi. I'm using GetOpenFileName function to do this. This function uses a structure to set options such as file extension filters. This structure's member called lpstrFilter needs a certain string format. I'm setting that string exactly as Winapi indicates, but for some reason, this string's value changes.

I've got this static const char *:

//This contains string "JPG"
static const char * extensionFilter = v->trabajo10.C_JMV_SelectFile_FileExtension7.GetString();

//This forms a filter string which applies to OPENFILENAME structure.
string sFilter;
sFilter.append("Format: ");
sFilter.append(extensionFilter);
sFilter.push_back('\0');
sFilter.append("*.");
sFilter.append(extensionFilter);
sFilter.push_back('\0');
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter; //This sets: --> Format: JPG\0*.JPG\0

//This opens the file selection dialog
if (GetOpenFileName(&ofn)==TRUE){
...

The File Selection Dialog looks CORRECTLY, like this:

enter image description here

The joke comes now, I modify the code like this:

//This contains string "JPG"
static const char * extensionFilter = v->trabajo10.C_JMV_SelectFile_FileExtension7.GetString();

if(1){
   //This forms a filter string which applies to OPENFILENAME structure.
   string sFilter;
   sFilter.append("Format: ");
   sFilter.append(extensionFilter);
   sFilter.push_back('\0');
   sFilter.append("*.");
   sFilter.append(extensionFilter);
   sFilter.push_back('\0');
   const char * filter = sFilter.c_str();
   ofn.lpstrFilter = filter; //This sets: --> Format: JPG\0*.JPG\0
}

//This opens the file selection dialog
if (GetOpenFileName(&ofn)==TRUE){
...

And this is the result, THE PROBLEM:

enter image description here

Filter string was modified???


Solution

  • if(1){
       //This forms a filter string which applies to OPENFILENAME structure.
       string sFilter;
       sFilter.append("Format: ");
       sFilter.append(extensionFilter);
       sFilter.push_back('\0');
       sFilter.append("*.");
       sFilter.append(extensionFilter);
       sFilter.push_back('\0');
       const char * filter = sFilter.c_str();
       ofn.lpstrFilter = filter; //This sets: --> Format: JPG\0*.JPG\0
    }
    

    The sFilter variable has a lifetime that ends when the block in which it declared ends. The pointer returned by sFilter.c_str() is valid until sFilter is modified or destroyed.

    You are using this pointer after it has become invalidated. This is the same problem as you had yesterday, which I guessed at in comments to the question. This is why you need to show a full MCVE. This question also looks to be a duplicate of the one that you asked a week ago: Winapi GetOpenFileName Extension Filter not working. I suggest that you take some time to make sure that you fully appreciate the validity of the value returned by c_str().

    You must ensure that sFilter lives until after you have finished with the pointer. Declare sFilter in an outer block to ensure that.