C++中的那些坑

本文总结了C++编程中的一些常见问题,包括变量初始化、多线程竞争、临时变量复制、宽字符跨平台问题等。同时,讨论了函数、类、代码规范、版本控制、汇编和链接以及SDK和第三方库的使用注意事项。强调了本地变量的使用、函数参数设计、类的构造与析构、代码规范和版本控制策略的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

学习一下公司大佬的C++课程,内容如题。

笔记:

几个常问题

问题1. 不初始化变量可能引起,在release下出现crash或死锁但是在Debug下正常运行,已经其它不可预测的运行结果,很难跟踪,所有变量最好在声明时就初始化,而且变量最好是需要使用时才声明,不要提前声明。

问题2. 程序只在Release下会崩溃或死锁,除了前面提到的变量为初始化,还有可能是因为:

  • 多线程竞争导致程序未按预期运行,出现资源无法满足(不理解)。
  • 由于性能的提高导致原本使用较少的资源出现了竞争。
  • 优化导致代码顺序改变或代码被意外优化掉了。

问题3. 像除0这样的操作会产生无意义的值NaN,用无意义的值NaN进行运算,会导致无明确定义的结果,在不同平台或编译器结果不一样,常见的运算结果是NaN、0。调试时可以使用std::isnan来进行捕获。

问题4. C++程序在启动过程中会初始化哪些变量

  • 静态初始化,编译时就确定值的全局变量或常量。
  • 动态初始化,函数(包括构造函数)计算获得值的全局变量。
  • 初始顺序是定义的顺序,销毁则是相反的顺序(注册到atexit)。

问题5. 函数内定义的静态变量,是在代码第一次执行时才初始化,并且就构造并初始化一次。虽然说第一次制作时才构造并初始化,该变量的空间占用确是程序执行前就会有了,和全局变量一样,销毁也和全局变量一样。

问题6. 怎么避免复制函数返回的临时变量?

  • 最简单的办法,将这个临时变量赋值给一个新变量,但是性能完全取决于拷贝构造函数,一般都不好。
  • 提供右值引用构造函数(A(A&& other)),或者右值引用复制构造函数(A& operator=(A&& other)),右值运算使用的std::move内部是对地址进行交换,没有复制操作,所以效率极高,右值概念是C++11及以后版本才有的。

问题7. wchar_t(宽字符) 的空间,Windows相关为2字节,Linux/Unix相关的为4字节,如果要考虑跨平台,不要使用wchar_t,可以使用uft8或utf16这种平台无关的编码

问题8. 代码的提交日志我们应该要写明什么内容?

  • 解决了什么问题,或添加了什么功能 what
  • 如果是解决问题,问题的根本原因是什么,为什么你的修改能修改掉这个问题 why
  • 是否还有遗留的问题或者需要注意的事项
  • 如果是新加功能,简单描述功能包含的内容

问题9. 单例模式有哪些写法?他们的问题是什么?

  • 使用全局静态变量、静态成员变量或本地静态变量,线程安全,用与不用都会存在,初始化顺序无法保证,难以控制对象的销毁,全局变量无法保证唯一性
  • 使用全局静态指针或静态成员指针,只有在使用时才会创建,线程不安全,需要自己处理多线程访问,可以提供销毁函数用于手动控制对象的销毁(如果后面有访问将会重新创建对象)
  • 使用本地静态指针,只有在使用时才会创建,C++11以上能保证线程安全,可以手动控制对象的销毁(如果后面有访问该对象程序将崩溃)

变量大总结

1.默认初始化,但其实内置变量如果没有特别处理,是不会初始化的,仅仅是在内存中占位声明。

unsigned count; // Default-initialized
unsigned count; // Default-initialized

2.值初始化

new unsigned();
unsigned count(); //有点像个函数调用
unsigned count{
   
   }; //C++11初始化数组,元素全部初始化为0

3.直接初始化

unsigned count(5
### 关于 MMDeploy 在 C++ 中使用的常见问题及解决方案 #### 错误处理与调试技巧 当在 Windows 下编译并尝试运行由 MMDeploy 生成的 C++ 应用程序时,可能会遇到各种错误。其中一种常见的问题是 `WinError126`,即找不到指定模块。此问题通常发生在迁移 DLL 文件至另一台计算机上之后[^2]。 为了克服这个问题,在目标机器上除了确保已复制必要的 `.dll` 文件外,还需确认这些依赖项能够被正确找到。可以利用工具如 Dependency Walker 来分析缺失的具体动态链接库,并按照提示安装相应的 Visual Studio Redistributable 或其他所需的第三方库版本。 #### 动态链接库路径配置 另一个需要注意的地方是在不同操作系统之间移植应用程序时,DLL 的搜索顺序有所不同。对于 Python 调用而言,可以通过设置环境变量 `PATH` 将包含自定义共享对象的位置加入到系统的查找路径中;而对于纯 C++ 程序,则可以在启动前通过编程方式调整加载器的行为: ```cpp #include <windows.h> // 设置当前工作目录下的 bin 子文件夹作为额外的 DLL 查找位置之一 SetDllDirectory(L".\\bin"); ``` 上述代码片段展示了如何修改进程级别的默认 DLL 加载策略,从而使得特定子目录内的资源更容易被识别和访问。 #### 编译选项优化建议 针对某些高级特性或硬件加速的支持(比如 TensorRT),可能需要特别指明构建参数以启用它们。例如,在使用 CMake 构建过程中传递 `-DMMDEPLOY_TARGET_BACKENDS="ort;trt"` 和 `-DMMDEPLOY_TARGET_DEVICES="cuda;cpu"` 参数可让最终产物兼容更多类型的计算设备[^3]。 此外,如果项目涉及到多个后端引擎的选择,务必仔细阅读官方文档了解各组件之间的兼容性和互操作性要求,以免因不恰当组合而导致不必要的麻烦。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值