winapi — C ++ Простое предложение IF меняет значение статической переменной const char

Хорошо, я занимаюсь этим уже два дня и не могу найти решение.

Проблема: Я пытаюсь установить фильтр на Диалог выбора файла используя Winapi. я использую GetOpenFileName Функция для этого. Эта функция использует состав установить параметры, такие как фильтры расширений файлов. Член этой структуры называется lpstrFilter нужен определенный формат строки. Я устанавливаю эту строку точно так, как указывает Winapi, но по какой-то причине значение этой строки изменяется.

У меня есть это статический константный символ *:

//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){
...

Диалог выбора файла выглядит ПРАВИЛЬНО, как это:

введите описание изображения здесь

Пришла шутка, я модифицирую код так:

//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){
...

И это результат, ЭТА ПРОБЛЕМА:

введите описание изображения здесь

Строка фильтра была изменена ???

-1

Решение

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
}

sFilter Переменная имеет время жизни, которое заканчивается, когда заканчивается блок, в котором она была объявлена. Указатель возвращается sFilter.c_str() действует до sFilter модифицируется или уничтожается.

Вы используете этот указатель после того, как он стал недействительным. Это та же проблема, что и у вас вчера, о которой я догадывался в комментариях к вопросу. Вот почему вам нужно показать полный MCVE. Этот вопрос также выглядит дубликатом того, который вы задали неделю назад: Winapi GetOpenFileName Расширение фильтра не работает. Я предлагаю вам потратить некоторое время на то, чтобы убедиться, что вы полностью оценили правильность значения, возвращаемого c_str(),

Вы должны убедиться, что sFilter живет до тех пор, пока вы не закончили с указателем. декларировать sFilter во внешнем блоке, чтобы обеспечить это.

5

Другие решения

Проблема в том, что у вас есть переменная, которая выпала из области видимости

if(1){
string sFilter;

// ... code

// Right here
const char * filter = sFilter.c_str();
ofn.lpstrFilter = filter;
}

После того, как этот блок заканчивается filter выходит за рамки, так ofn.lpstrFilter имеет висячий указатель.

2

Отвечая на вопрос ProtectedVoid по поводу объявления неиспользуемого объекта: представьте себе std::string был дорогой объект, и состояние было маловероятным. Вы не хотите, чтобы объект был построен, если условие не выполняется. Но тогда это должно продолжаться за рамками условия. Таким образом, мы используем тот факт, что по умолчанию построен unique_ptr намного дешевле, чем построенный по умолчанию string:

std::unique_ptr<std::string> scope_extender;
if( something unlikely ){
//This forms a filter string which applies to OPENFILENAME structure.
std::string* sFilter = new std::string;
scope_extender.reset( 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
}

Очевидно, я не хочу подразумевать std::string достаточно дорого построить, чтобы стоить всех этих хлопот. Но какой-то объект в подобной ситуации может быть. Также был комментарий о том, что если бы было много второстепенных объектов в одном условном выражении. В этом случае вы бы хотели, чтобы служебная структура содержала их все вместе, а unique_ptr условно владеет этой структурой.

0
По вопросам рекламы [email protected]