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