通用问题
一、结构体用char*,char[],还是string?
在 C++ 编程中,领导坚持用 char 而不用 string,string 有那么可怕吗? - 包包包子的回答 - 知乎
1.1.对外提供接口情况时 使用char[]最好
- 不让用string 很多的是考虑 api接口的简洁,兼容性。dll 导出 stl 这种模板库 简直是灾难,很不好解决。而且要考虑内存分配与释放问题,必须在同一个模块进行,跨dll要出问题的。 导出dll 一般都用 c风格的api 这样客户也好理解,避免各种问题。
- string在c++标准中自定义了接口,没有定义具体实现,各标准库对他的实现不一。
- 跨平台一般是C风格接口更容易被其他平台调用
- 跨平台返回std::string 容易产生跨dll释放问题
1.2 对内 业务上尽量使用string
业务上肯定要string,毕竟string好使,尽量用引用,这样能减少内存拷贝,而且在客户端编程里面,string肯定非常常用。虽然客户端没有高性能要求,但还是要注意性能,我见过很多项目,项目代码量不大,但是就是很卡。
二、MAX_PATH为啥是260?
三、指针
3.1 二级指针和指针数组
二级指针:指向一堆一级指针起始地址的指针,只是指针 4个字节 32位大小,没有创建任何空间,所以里面内容需要每次new,一级指针内容也需要new。
指针数组:存放一级指针数组,有一段有限内存存放若干数量的指针,n个4个字节的指针,但每个一级指针的内容需要new出来。
void GetIntArr(int ** &ppInt,int &size) { size = 10; ppInt = new int*[size]; for (size_t i = 0; i < size; i++) { ppInt[i] = new int; *(ppInt[i]) = i; } } void main(void) { int **ppInt = NULL; int size = 0; GetIntArr(ppInt,size); for (size_t i = 0; i < size; i++) { printf("%d\n", *ppInt[i]); } system("pause"); }
三、std::string重复销毁问题
3.1 起因:用string作为外部接口
四、返回引用函数 引用作用范围结束后会调用析构函数
五、Debug\Release 导致运行结果不同
5.1 起因:结构体没进行构造初始化
Debug可能默认是0值
Release默认是随机值
六、long和longlong长度
longlong 类型 http://c.biancheng.net/view/7809.html
建议用stdint.h 跨平台类型
建议用void* 作为map的key 因为 程序多少位
七、std容器常见问题
7.1 std::map
map 通过键值查找,判空问题
正确示范
std::map mapTest; ... if(mapTest.find(element) != map.end()){ //存在 mapTest[key]; }
错误示范
std::map mapTest; ... if(mapTest[key] != nullptr){ mapTest[key]; }
原因:直接使用map[key]方式访问不管是否存在Value,都会创建一个Value,从而试判断出错。
7.2 std::vector
八、内存泄漏
8.1 代码层解决
1.MFC 宏 DEBUG_NEW
2.Win32 C库 Debug Routines
最重要的是 _CrtDumpMemoryLeaks使用这个函数,需要包含头文件crtdbg.h
该函数只在Debug版本才有用,当在调试器下运行程序时,_CrtDumpMemoryLeaks 将在“Output(输出)”。
3.重载new/delete
4.类似JUCE库 添加LEAKDECTOR
5. wpa 查看内存增长的exe 对应的函数
Visitual Studio
一、编译问题
1.1 error C1041: 无法打开程序数据库
error C1041: 无法打开程序数据库“xxx\vc140.pdb”;如果要将多个 CL.EXE 写入同一个 .PDB 文件,请使用/FS
原因: 项目用了同一个tmp文件夹
解决方案: 中间文件夹重命名
1.2 全局变量使用问题
无需引入头文件,只用在所引用的cpp文件前extern,引入全局变量所在头文件,会引起重复定义问题。
二、换行符问题
起因
windows创建的文件是 \n\r结束的, 而linux,mac这种unix类系统是\n结束的。
所以unix的文本到windows会出现换行丢失(ultraedit这种软件可以正确识别); 而反过来就会出现^M的符号了
windows换行是\r\n,十六进制数值是:0D0A。
LINUX换行是\n,十六进制数值是:0A
三、调试代码错位问题
起因
- 代码换行格式改变了,Unix(LF)的格式和Windows(CR LF)切换了导致
- 代码中有中文注释而又使用LF
解决办法
对应1是需要把换行改为代码默认的换行格式
对应2是把带有中文注释的地方 末尾加个 .
推荐使用dos2unix 批量转换 比较方便且中文转换过程不会乱码
四、常见警告及错误
4.1 调用socket库函数 过时
error C4996: ‘gethostbyname’: Use getaddrinfo() or GetAddrInfoW() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
解决方法1 添加宏
#define _WINSOCK_DEPRECATED_NO_WARNINGS
解决方法2 使用新的socket库函数
4.2 调用字符串库函数过时或者不安全
error C4996: ‘strcpy’: This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
解决方法1 关闭警告
#pragma warning(disable:4996)
解决方法2 使用安全的字符串库函数