首页 > 其他分享 >记一则由临时对象引起的 bug

记一则由临时对象引起的 bug

时间:2022-09-02 17:24:41浏览次数:56  
标签:std string title 临时 ofn lpstrTitle str 一则 bug

最近在用 imgui 写一个数据对比工具,里面需要使用 Win32 函数来选择文件路径。相关代码差不多是这个样子:

std::string GetOpenFilePath(const std::string &title) {
  char path[MAX_PATH];

  OPENFILENAME ofn;
  ofn.lpstrTitle = title.c_str();  // 设置对话框标题
  ofn.lpstrFile = path;
  ofn.nMaxFile = MAX_PATH;
  // ...

  if (!GetOpenFileNameA(&ofn)) {
    // error
    return {}; 
  }

  return path;
}

由于在程序中使用了 utf8 编码,而 Win32 需要 GBK 编码,故需要处理编码转换的问题。所以代码改成了这样:

// 为了避免“谁来释放内存”这种问题,转换函数直接返回了 std::string
std::string GbkToUtf8(const std::string &gbk_str);
std::string Utf8ToGbk(const std::string &utf8_str);

std::string GetOpenFilePath(const std::string &title) {
  // ...
  ofn.lpstrTitle = Utf8ToGbk(title).c_str();
  // ...
  
  return GbkToUtf8(path);
}

结果导致对话框标题一直是乱码。这是因为: Utf8ToGbk(title) 返回了一个临时对象,临时对象在当前表达式求值完成时会被销毁。导致后面调用 GetOpenFileNameA 时,lpstrTitle 指向的字符串其实已经被销毁了!

关于临时对象的销毁时机,C++ 标准文件 N486 6.7.7 描述如下:

Temporary objects are destroyed as the last step in evaluating the full-expression (6.9.1) that (lexically) contains the point where they were created.

解决方法很简单,只要将临时对象变为局部对象即可。

- ofn.lpstrTitle = Utf8ToGbk(title).c_str();
+ std::string t = Utf8ToGbk(title);
+ ofn.lpstrTitle = t.c_str();

顺带一提,将临时对象(函数的返回值)赋值给局部变量,并不会导致额外的一次拷贝构造。这就是所谓的返回值优化Return Value Optimization)。

标签:std,string,title,临时,ofn,lpstrTitle,str,一则,bug
From: https://www.cnblogs.com/fchen99/p/16650619.html

相关文章

  • 临时邮箱哪个好
    在某些平台或者网站浏览时,需要用临时邮箱注册账号,才能正常访问。如果用常用的个人邮箱注册账号,很容易收到大量的推广邮件,甚至账号信息被泄露。因此,一个好用的临时邮箱非常......
  • MRS There is a hole [0x212-0x229] in .debug_loc section. 报错
      这个警告产生是因为MRS删除DEBUG定义导致,要消除警告MRS设置需要更改一下 ......
  • EDK2+Vscode Build Debug 环境配置
    配置shell环境使用工作区配置.vscode/settings.json "terminal.integrated.env.linux":{  "WORKSPACE"   :"${workspaceFolder}",  "EDK_TOOLS_PA......
  • jira提交bug
    1:jira通过浏览器链接打开  2:菜单栏-点击项目,选择对应的项目   3:菜单栏-点击新建;或者快捷键C,则跳出创建问题的弹框  4:问题类型选择:缺陷  5:编写缺......
  • 【C++】Debugging Segmentation Faults
     背景linux下的程序,在遇到空指针解引用、栈错误等原因崩溃时,bash会输出一条:Segmentationfault(coredump)如果你看到coredumped字样,并且在目录下也找到了一个叫co......
  • Dynamic debug方法
    1、在内核配置时打开CONFIG_DYNAMIC_DEBUG宏。2、控制某个文件echo-n"filexxx.c+p">/sys/kernel/debug/dynamic_debug/control3、控制某个函数echo-n"func......
  • 并发编程Bug起源:可见性、有序性和原子性问题
    以前古老的DOS操作系统,是单进行的系统。系统每次只能做一件事情,完成了一个任务才能继续下一个任务。每次只能做一件事情,比如在听歌的时候不能打开网页。所有的任务操作都按......
  • 1[代码解析005] 关于一次bug排查解析 | new出一个对象其属性默认值是?
    1、代码片段//子单据状态更新List<OutboundOrderDetails>updateOutboundOrderDetailsList=Lists.newArrayList();outboundOrderDetailsLis......
  • andv table row-selection的bug记录
    antdv版本:^3.2.9下面全部代码<template><div><divstyle="margin-bottom:16px"><a-buttontype="primary":disabled="!hasSelected":loading="loadin......
  • 花了两天时间搞定的bug:Unable to convert the Pixel Data as the 'pylibjpeg-libjpeg'
    BUG发生场景:在使用Pydicom包读取含下列压缩类型中的JPEGLossless(Process14,SV1)的dcm图像时,由下图可知需要安装GDCM或者pylibjpeg才能进行正常读取。然而,笔者不仅仅安......