new完不能delete?菜鸡记一个有趣的简单BUG,绝不再犯!

本菜鸡遇到一个简单而有趣的bug竟然困扰了挺久。记录一下,绝不再犯!

背景: 做个Demo,需要统计编码完每帧图像的相关信息,比如码率、质量、编码参数等信息。

内容

  1. 因为参数分布在不同的文件和函数里面,编码帧数不确定,所以定义了一个全局变量(指针)。
int* InfoRecord = NULL;
  1. 在根据YUV文件大小、宽高、采样信息确认了编码总帧数之后,给指针动态分配内存。
InfoRecord = new int[totalFrames / gopLenth + totalFrames % gopLenth > 0 ? 1 : 0];
  1. 调用编码器编码,调用解码器解码,根据 frameIdx 填写到对应的 InfoRecord 里面。
  2. 信息输出结束,释放内存。
delete[] InfoRecord;
InfoRecord = NULL;
delete InfoRecord;

问题出现!release没问题,debug时有时无地进行报错,修改编码参数就会影响报错的频率!
new完不能delete?菜鸡记一个有趣的简单BUG,绝不再犯!_第1张图片

就这个问题,我一脸懵逼??? new了之后竟然不能delete!!!

  • 我一开始认为 “我定义的全局指针在全局变量区,动态分配的内存在堆区,难道因为牵扯了全局变量区,这堆区的内存不能让我来释放???系统要帮我管理???

  • 于是用VS debug 查看内存,结果是我想得太简单了,在我令 “InfoRecord = NULL; ”之后,指针分配的内存仍然没有被释放,new完不delete果然内存泄漏!!!

在这里插入图片描述

  • 咋办呢 ? 我问了旁边实习的正统计算机本硕的同学,人家说:“卧槽,还有这种事?我也没见过。"
  • 但是,他给我个好解决方法:“你认为是牵扯了全局变量区所以不能自己释放!我觉得有道理!那你按照下面这种写法不就好了”。

① 依旧定义那个全局变量(指针)。

int* InfoRecord = NULL;

② 不要直接对着 InfoRecord 分配内存,先弄个局部变量指针分配内存,再浅拷贝,再释放这个局部变量指针!

int InfoRecordTmp = new int[totalFrames / gopLenth + totalFrames % gopLenth > 0 ? 1 : 0];
int InfoRecord =InfoRecordTmp;

③ 之后再释放内存。

delete[] InfoRecordTmp;
InfoRecordTmp = NULL;
delete InfoRecordTmp;

......

delete[] InfoRecord;
InfoRecord = NULL;
delete InfoRecord;

有理啊! 牛掰!
开心解决了这个BUG!!!
结果又是下图:
new完不能delete?菜鸡记一个有趣的简单BUG,绝不再犯!_第2张图片

???????临时变量指针都不能delete???????
??????????你是魔鬼吗 ??????????
??????程序员生涯还没开始就结束了??????

后来,我在百度、google、csdn上搜索各种“全局变量指针” “new完不能delete”等关键词,都没有能帮我解决的答案。
还去问了实验室同学,最后我竟然认为是超出能力范围的内存管理问题。

new完不能delete?菜鸡记一个有趣的简单BUG,绝不再犯!_第3张图片
new完不能delete?菜鸡记一个有趣的简单BUG,绝不再犯!_第4张图片
费时费力仔细排查后发现,竟然是=====================》!!!!!!划重点!!!!!!


本菜鸡忽视了运算符顺序导致new操作时大小出错了!

错误:

InfoRecord = new int[totalFrames / gopLenth + totalFrames % gopLenth > 0 ? 1 : 0];

三目运算符 ? : 优先级比 + 低,new的大小出错,导致后面释放不了!就是少了一个括号的问题!

改成:

InfoRecord = new int[totalFrames / gopLenth + (totalFrames % gopLenth > 0 ? 1 : 0)];

菜鸡啊!C++运算符优先级这种最基础、最基础的问题都弄错了,还在那里乱扯一通堆栈、全局变量区啥的玩意,真是基础太差!下表罚抄10遍!

new完不能delete?菜鸡记一个有趣的简单BUG,绝不再犯!_第5张图片

你可能感兴趣的:(视频编解码)