指针越界破环堆结构引起的崩溃问题 – realloc(): invalid next size
单步调试C++程序遇到一个之前未遇到的问题,详细记录一下排查过程。
情况说明
使用Vscode IDE进行程序单步调试过程中,状况一是没有顺序执行单步程序,而是乱序执行
;状况二是在opencv调用img.clone() 进行图片深拷贝时报错
,前提是已经查看了图片的信息确定读取到了一张图片。
排查过程
1. 问题一:乱序执行
原因在于CMakelists中编译优化选项
的问题,乱序执行状态,设置如下
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -pthread -fopenmp")
-O3
的编译优化,使得程序不按照正常顺序执行,而是以不影响结果的提前下,改变了指令执行顺序,不方便单步调试,可以将其注释掉。
2. 问题二: 在Opencv库函数 .clone()中的copyTo() 崩掉
阶段一
开始认为是函数使用不当,但是发现诡异的情况,我的调用关系如下,在func1中调用了func2,在func2中进行图片的深拷贝,func1中…并未对图片进行处理。
void func1(cv::Mat& img){
...
func2(img);
}
void func2(cv::Mat & img){
auto res_img = img.clone(); // ***崩溃位置
...
}
查询相关opencv api
,也更换了api copyTo()
进行尝试,依旧无果。但是过程中在func1函数参数传入之前,进行图片的深拷贝就没问题,此处便是迷惑之处。形式如下:
auto res_img = img.clone(); // ***没问题
func1(img);
阶段二
调试过程中将func1中的 … 操作注释掉,此时发现func2中的图片深拷贝又可以了。此时意识到func1中的...操作
产生了问题,但是… 操作并未对图片进行处理,那么怎么会对cv::Mat产生影响?
查看func1中的…操作,主要是针对指针的操作,在堆上开辟了一段内存,通过指针进行内存读写,形式如下:
/* func1中的 ... 操作 */
float *p = new float[100];
for(int i=0; i<1000; ++i){ // *** 形式如此,真实不是这么简单,反正指针越界进行了写操作
*(p+i) = 1;
}
至此出现标题中的问题:realloc(): invalid next size
,最终原因就在于在func1中对指针操作越界了,修改了cv::Mat内存中的某些字段,导致了崩溃的问题。
总结
排查过程中,出现了错误的状态,如果程序中存在指针的操作
,一定要注意。有可能出现此类状况,出现错误的地方,不一定是真正错误的地方,而是指针非法操作间接导致的。