报内存错误的代码:

在这里插入图片描述

顺利执行的代码:

在这里插入图片描述

可以看到在malloc为a开好空间,然后对自定义类型对象a中的string a成员进行赋值的时候,发生了内存错误,但是经过测试,使用new为string a开空间就不会发生错误;

new和malloc最本质的区别

最主要的本质区别:new会调用开空间对象的构造函数,malloc不会简单无脑直接开空间;

关于new操作符底层封装malloc,加了抛异常机制,还有他们用法上的区别这些就不谈了;

这样,上面malloc string的问题就可以解释了;


原因

首先C++内置string字符串自定义类型,一般new为string开空间的时候,string底层会在 构造函数调用过程中 在堆上再开一个char*的空间(malloc或者new为string开了空间,而string的构造函数还得为内部成员char*再开一个空间的),这个二次开的空间相当于是个变长数组,用于存放一个个的字符;(vector,queue等存储容器都是这样的机制)

那么我们malloc简单无脑的为string开了空间以后,不调用string人家的构造函数导致string内部这个堆上存放字符的空间没开出来,接着我们往string a中放字符的肯定就会放不进去啦,直接内存错误,因为你都没地方怎么放

new的话,调用了string的构造函数,内部的空间开出来了,当然就没问题了,能放字符进去了


分析

其实这怪不得malloc太简餐粗暴,也怪不得string太复杂;

malloc本来就是和C一起诞生的,C中本来就没C++封装的这种概念,完全不会出现上面malloc string这种需要在底层自己再开一块空间的现象,人家用malloc舒服着呢;

C++有了封装,支持了面向对象,当然好处多多,也为此配套了new这种不会产生问题的开空间方式,只是语言特性,C++为了支持C,malloc也流进来了,导致这种混搭错误的出现;

所以以后写程序的时候多多注意就行,new和malloc开空间的时候思考几秒用哪个,当然我个人感觉能用new就别malloc了,new毕竟适配性更高了不是吗;

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐