内容纲要
回老家过新年,在老家码代码。由于对于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 ;
后记
哟西,可以了。