前言
今天在用C++的时候,碰到了一个比较棘手的问题——在创建结构体指针的时候指针的数据成员始终没有自动初始化,不等于我设置的默认值。即使我显式的在构造函数为其初始化,依旧没正确赋值,是随机的。显然是没有调用构造函数。
经过排查发现,通过malloc创建的对象是不会对数据成员进行初始化的,也就是说不会调用构造函数的!这是为什么呢?这要搞明白malloc及new的性质,同时搞清楚它们的区别。
解决方案:使用new操作符代替malloc创建对象
new操作符与malloc函数的区别
从对象所分配的内存空间位置上来看:new操作符为对象动态分配自由存储区(free store)上的内存空间,而malloc函数从堆上动态分配内存。
- 自由存储区是C++基于new操作符的一个抽象概念,凡是通过new申请到的内存,这块内存就被称为自由存储区。
- 堆是操作系统层面上的概念,是操作系统所维护的一块特殊内存,用于程序的动态内存分配。
- 自由存储区可以是堆,也可以不是,这取决于具体实现。(默认情况下C++编译器会使用堆来实现自由存储)
返回值类型不同:new操作符内存分配成功时,返回的是对象类型的指针,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void* ,需要通过强制类型转换将void指针转换成我们需要的类型。
是否执行生命周期函数:new会调用对象的构造函数/析构函数完成对象的构造和析构操作;而malloc不会。这就是为什么通过malloc创建的对象是不会对数据成员进行初始化的,对其数据成员的默认值是随机的,即使指定默认值,依然是随机的。这也是两者最大的区别。
其他:
是否重载:new操作符可以重载;而malloc是库函数,不能重载
内存分配失败时的处理策略不同: new操作符在内存分配失败时会抛出bad_alloc
异常,它不会返回NULL;malloc在内存分配失败时返回NULL
内存不足时的处理方式:malloc分配的内存不足时,可以用realloc扩容;而new没有这样的配套设施
new/delete是c++中的运算符,而malloc/free是c++/c都支持的库函数.