这两天在写一个视频转换的程序,将H263/264编码的视频封装成mov格式,用c++实现。
Wiki上说Apple的mov格式是典型的over engineering,设计的非常复杂,各种信息使用atom原子封装,一个atom里面递归地嵌套着另外一个atom,atom的种类有几十种之多,用类实现是再好不过了。
发完牢骚了,言归正传,以前没怎么做过c++的东西,或者更本质地说,没怎么写过面向对象的程序,所以很2B地将类对象做为函数的参数,好了,问题来了。
现在有一个TMovMediaFile类,用来存储生成mov文件需要的各种信息,在新生成的mov文件中需要重新计算媒体数据的位置,即chunkOffset,chunk是保存媒体信息的数据块。现在写了这么个函数,来更新chunkOffset
Bool updateChunkOffset(int changeValue,TMovMediaFiletmov)
编译通过,运行,报错,double free or corruption.
TMovMediaFile类的析构函数被执行了两次,c++里面函数参数传值和传引用的区别一下体现出来了。
如果是上面的写法,那么程序会创建一个tmov的临时副本,函数执行完了,就会执行TMovMediaFile类的析构函数,因为这个副本只是一些指针,指向一些new申请的地址空间,所以原先的TMovMediaFile对象tmov等于也是被析构了,函数的形参和实参指向的是同一片new申请到的内存,那么等主程序退出,再次执行tmov的析构函数就会发生重复delete的错误。
使用TMovMediaFile&做传引用调用,就不会有这样一个问题,update函数执行完毕不会对tmov进行析构,因为tmov对象在main中创建,只有main执行完了,才会调用它的析构函数,所以不会发生重复析构的问题。
PS:在一个比较长的程序里面找重复析构的地方还是很费劲啊,面对c++,我只是菜鸟。