之前写过,当类对象作为参数,传入函数的时候,在函数内部,进行对类的操作,有的会生效,有的不会,当将类的指针对象传入的时候,就不会不生效。
今天同样遇到,将数组指针指针当作参数,传入函数的时候也失效了。就是说,在函数中获得数组的值是错误的。给我的感觉,c++用起来很不安全,好多坑,当然,c++ 用的少自己菜的原因。可能是针对c++ 的 变量的生命周期了解不够透彻。
下面给出例子:
int *OpenglShow::getsShowSize(int w ,int h)
{
int newH = 0;
int newW = 0;
float rWin = float( w)/ float(h);
float rFra = float(windowHeight)/ float(windowWidth);
if(rWin > rFra )
{
newH = windowHeight;
float r = float(newH)/ float(h);
newW = int(r * w);
} else{
newW = windowWidth;
float r = float(newW)/ float(w);
newH = int(r * h);
}
// int] *size = new int[2];
// size[0] = newW;
// size[1 = newH;
//这种返回值,是个局部变量,size里面的值 会改变,也就是说size会被回收。导致后面draw的时候,值已经改变
int size[2] ={newW, newH};
return size;
}
上面的代码,是视频播放器中,根据视频size获得 播放的size的函数,最终返回的是一个数组,里面装的是宽 和高。
下面是调用部分:
void OpenglShow::show(AVFrame *avFrame)
{
int w = avFrame->width;
int h = avFrame->height;
int *showSize = getsShowSize(w,h);
LOGE("newW0 =%d, newH0=%d", showSize[0], showSize[1] );
int size[2] = {showSize[0], showSize[1] };
LOGE("newsize0 =%d, newsize0=%d", showSize[0], showSize[1] );
switch(avFrame->format)
{
case AV_PIX_FMT_YUV420P:
getYUV420pData(avFrame);
glProgram->Draw(w,h,y,u ,v ,AV_PIX_FMT_YUV420P ,showSize);
break;
case AV_PIX_FMT_NV12:
getNV12Data(avFrame);
LOGE("newW =%d, newH=%d", showSize[0], showSize[1] );
LOGE("newWsize =%d, newWsize=%d", size[0], size[1] );
glProgram->Draw(w,h,y,u , nullptr ,AV_PIX_FMT_NV12 ,size);
break;
case AV_PIX_FMT_NV21:
getNV12Data(avFrame);// 与getNV12Data 一样的,只是在着色器里面取 U V的顺序不同
glProgram->Draw(w,h,y,u , nullptr ,AV_PIX_FMT_NV21,showSize );
break;
}
LOGE("newWsize2 =%d, newWsize2=%d", size[0], size[1] );
LEGL::Get()->Draw();
av_frame_free(&avFrame);
}
通过log:
getsShowSize 返回的值,刚开始是对的,但随后,读取赋值给size数组的时候变了,在switch的时候,showSize又改变了,,在函数里面用一个 size数组,来记录,到了调用的时候 又改变了。
当把 getsShowSize 里面返回的size 改为 new的形式,返回,则就不会出现这问题,这说明,getsShowSize返回的数组后面执行代码的时候被回收了。
总结:
1、在函数返回数组的时候,内存一定要new,当然后续要记得释放。
2、函数如果不是new出来的,它的生命周期就在本函数内,出了函数就可能被释放,因此,getsShowSize 内部定义数组size,在返回值后就释放了。
之前一个项目中,向vector中存储一些数组,但后续发现所有的变量都是一样的了。大致是这样:
int size[2];
for(int i = 0 ; i < 100; i++)
{
int w = getW(i);
int h = getH(i);
size[0] = w;
size[1] = h;
vector.push_back(size);
}
最后也是,将压入的数据都 new 出来 后就不会出错,否则函数不会 申请size的空间一直重复利用,最终压入栈的内容全部是最后一个size的值,压入栈的其实都是开始申请的size。