[笔记]c++ 常见问题

通用问题

一、结构体用char*,char[],还是string?

在 C++ 编程中,领导坚持用 char 而不用 string,string 有那么可怕吗? - 包包包子的回答 - 知乎

1.1.对外提供接口情况时 使用char[]最好

  1. 不让用string 很多的是考虑 api接口的简洁,兼容性。dll 导出 stl 这种模板库 简直是灾难,很不好解决。而且要考虑内存分配与释放问题,必须在同一个模块进行,跨dll要出问题的。 导出dll 一般都用 c风格的api 这样客户也好理解,避免各种问题。
  2. string在c++标准中自定义了接口,没有定义具体实现,各标准库对他的实现不一。
  3. 跨平台一般是C风格接口更容易被其他平台调用
  4. 跨平台返回std::string 容易产生跨dll释放问题

1.2 对内 业务上尽量使用string

业务上肯定要string,毕竟string好使,尽量用引用,这样能减少内存拷贝,而且在客户端编程里面,string肯定非常常用。虽然客户端没有高性能要求,但还是要注意性能,我见过很多项目,项目代码量不大,但是就是很卡。

二、MAX_PATH为啥是260?

MFC 中_MAX_PATH的理解
解决路径超过MAX_PATH问题

三、指针

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 代码层解决

C++代码中的内存泄漏检查如何做?(一)

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

三、调试代码错位问题

起因

  1. 代码换行格式改变了,Unix(LF)的格式和Windows(CR LF)切换了导致
  2. 代码中有中文注释而又使用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 使用安全的字符串库函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二进制怪兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值