一个常见的Bug

内容纲要

回老家过新年,在老家码代码。由于对于C++特性不熟悉,一些应该删掉copy constructor的类没删,导致了一个deconstructor重复调用的问题,这个问题还是蛮常见的,写在这里提醒一下自己。

正文

问题产生的具体场景是这样的,我写了一个结构体Buffer用于绑定一段GPU内存,在~Buffer()中摧毁了对应的GPU上的内存分配。但很鬼扯的事情发生了:我没有删掉Buffercopy constructor。显然Buffer的拷贝算符在任何情况下都不应该被调用。

但是我老年人了,大意了,没发现。接着我犯下了第二个错误,在某个类下面写了一个Buffergetter,形如:

Buffer getIBuffer () const ;

这个getter函数声明也是很有问题的,它会将Buffer复制一遍再返回而不是直接返回,这就导致会同时存在两个相同的Buffer,而这两个相同的Buffer绑定的是同一段GPU内存。在两个Buffer都存活的期间是暂时看不出什么问题的,但一旦其中一个Buffer掉出生命周期,deconstructor被调用,那么另一个Buffer所绑定的GPU内存也被释放了,就会出现令人迷惑的Bug。

这意味着,一旦该getter被某些逻辑调用,此Buffer很可能在短时间内就会被偷偷释放!

该Bug具体症状表现为:加载到GPU内存的Buffer在提交渲染的时候莫名其妙地“消失”了。

由于Hineven开始用C++新特性还不太久,曾经没有见到过类似的Bug,一开始根本没往这边想。幸好该Bug症状不容易和其它Bug混淆,不然可能好几天都发现不了问题的根源。

解决方法很简单,删掉Buffer类的copy constructor即可,这样编译器会提醒你所有可能的错误。

Buffer (const Buffer & b) = delete ;

getter也改一下:

const Buffer & getIBuffer () const ;

后记

哟西,可以了。

此条目发表在学习分类目录,贴了标签。将固定链接加入收藏夹。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注