内容纲要
回老家过新年,在老家码代码。由于对于C++特性不熟悉,一些应该删掉copy constructor的类没删,导致了一个deconstructor重复调用的问题,这个问题还是蛮常见的,写在这里提醒一下自己。
正文
问题产生的具体场景是这样的,我写了一个结构体Buffer用于绑定一段GPU内存,在~Buffer()中摧毁了对应的GPU上的内存分配。但很鬼扯的事情发生了:我没有删掉Buffer的copy constructor。显然Buffer的拷贝算符在任何情况下都不应该被调用。
但是我老年人了,大意了,没发现。接着我犯下了第二个错误,在某个类下面写了一个Buffer的getter,形如:
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 ;
后记
哟西,可以了。