又到公司代码评审了,每次都能找到一些幺蛾子,看看这次又是什么?最近新来了几个实习生,希望对代码下手轻点。
小看半小时,代码问题不大,都是一些细节问题。喝口82年的咖啡压压惊,再继续评审吧。
有妖气!代码中看到了大量的malloc和free,代码大概是这样子的:
代码语言:javascript复制class Car
{
public:
Car() { }
};
Car *car = (Car *)malloc(sizeof(Car));
free(car);
居然对一个类下手,用的是malloc,看起来和平时的不一样啊。直觉编程:看起来很奇怪,那么它很大概率有问题。
指针类一般使用new创建或delete删除,但使用malloc和free有点C语言风格的味道了。看起来怪怪的,但是找不到问题所在,有点气啊。
代码评审有时候挺好的,遇到不懂的问题又可以学习了。既然一般指针类的创建和销毁是使用new或delete,而代码中使用了malloc和free,那就看看它的定义,看看有什么区别。
那就找找C 帮助手册呗(cppreference.com
),看完malloc和new的C 帮助手册说明,大概知道上面代码中使用不恰当的地方了,我们先看下手册是怎么说明的吧。
malloc
:任何情况下,此函数不调用构造函数或初始化内存。不保证调用匹配的解分配函数的预备使用的智能指针。C 中偏好的内存分配方法是用 RAII 预备函数 std::make_unique 、 std::make_shared 、容器构造函数等,而在低层代码中为 new 表达式。new
: new 表达式所创建的对象按照下列规则初始化:对于非数组的类型,在所得内存区域中构造单个对象。若无初始化器,则对象被默认初始化。若初始化器 是带括号的实参列表,则对象被直接初始化。若初始化器 是花括号包围的实参列表,则对象被列表初始化。
从上面的帮助说明中得出:malloc创建的类是不能调用类的构造函数的,而new则会调用类的构造函数。同样地,free销毁类也是不能调用类的析构函数的。
如果类内有指针成员,需要在构造函数中初始化,而实际上用了malloc创建类,没能调用构造函数初始化,最后会导致意想不到的后果(内存访问错误导致崩溃)。
问下当事人说:我这是故意的,因为malloc创建的类不会调用构造函数,这样就可以让程序执行少一些代码,从而提高运行效率。
看着他得意地说得头头是道。我只能躲在角落瑟瑟发抖,心里默默念:我不干了!!!
malloc
帮助手册说明地址:
https://zh.cppreference.com/w/cpp/memory/c/malloc
new
帮助手册说明地址:
https://zh.cppreference.com/w/cpp/language/new