free():vector <vec4i> c ++的无效指针[关闭]

Posted

技术标签:

【中文标题】free():vector <vec4i> c ++的无效指针[关闭]【英文标题】:free(): invalid pointer for vector<vec4i> c++ [closed] 【发布时间】:2012-12-12 23:46:41 【问题描述】:

我的问题是 std:vector&lt;vec4i&gt; ( p_lines and filt_lines) 是在函数中创建的,不能在函数末尾释放。所以我在运行代码时收到free(): invalid pointer 错误。在某些情况下,我会出现分段错误错误,但我无法使用 gdb 跟踪源。 该函数的目的是找到图片上的边缘和交叉点,在大多数线条相交的区域中,它会淹没一个矩形。图片来自 ROS 视频源。

void Probabilistic_Hough( Mat src, Mat &result )

    result=src;
    cvtColor( src, src, CV_RGB2GRAY );
    Canny( src, src, 50, 200, 3 );
    HoughLinesP( src, p_lines, 1, CV_PI/180, 85, 40, 10 );  
vector<Vec4i> filt_lines;
        int fls=filt_lines.size();
        int pls=p_lines.size();
if (!p_lines.empty())
    for(size_t i = 0; i < p_lines.size();i++)
    
        Vec4i l = p_lines[i];
        if ((l[0]<l[2]-10 ||  l[0]>l[2]+10) &&  (l[1]<l[3]-10 || l[1]>l[3]+10))
        
            line( result/*probabilistic_hough*/, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(255,0,0), 2);
            filt_lines.push_back(l);

        

    


    fls=filt_lines.size();
    pls=p_lines.size();
    printf("f=%d p=%d",fls,pls);
    if (filt_lines.size()>1 && !filt_lines.empty()) 
    
        int sizeX=src.rows/11, sizeY=src.cols/11;
        int imgGrid[11][11];

        for (int i=0;i<11;i++)
        
            for (int j=0;j<11;j++) imgGrid[i][j]=0;
        


        for (size_t i = 0;i<filt_lines.size()-1;i++)
                   
            Point2f o1 (filt_lines[i][0], filt_lines[i][1]) ;
            Point2f p1 (filt_lines[i][2], filt_lines[i][3]) ; 
            for (size_t j=i+1;j<filt_lines.size();j++)
            
                Point2f o2 (filt_lines[j][0], filt_lines[j][1]) ;
                Point2f p2 (filt_lines[j][2], filt_lines[j][3]) ;
                Point2f x = o2 - o1;
                Point2f d1 = p1 - o1;
                Point2f d2 = p2 - o2;
                float cross = d1.x*d2.y - d1.y*d2.x;
                if (abs(cross) > 1e-8)
                
                    double t1 = (x.x * d2.y - x.y * d2.x)/cross;
                    Point2f crosP  = o1 + d1 * t1;
                    if (crosP.x>0.0 && crosP.y>0.0 && crosP.y< src.rows && crosP.x<src.cols)
                    imgGrid[int(crosP.x/sizeX)][int(crosP.y/sizeY)]++;
                
            
        
        int countP=0,maxi=0, maxj=0;
        for (int i=0;i<11;i++)
        
            for (int j=0;j<11;j++)
            

            if (countP<imgGrid[i][j])
                
                    countP=imgGrid[i][j];
                    maxi=i;
                    maxj=j;
                
            
        
        printf("c=%d \n",countP);
        if (countP>0)
        
            Point vanishP1 = cvPoint(maxi*sizeX,maxj*sizeY), vanishP2 = cvPoint((maxi+1)*sizeX,(maxj+1)*sizeY);
            CvScalar red= CV_RGB(220,0,0);
            if (vanishP1.x>=0 && vanishP1.y>=0 && vanishP2.x>0 && vanishP2.y>0)             
            rectangle(src,vanishP1,vanishP2,red,2,8,0);     
            result=src;
         else printf("only 1 intersection, out of img"); 
     else 
    
    printf("No filtered lines");
    


 else 
           
    printf("no lines on image");
    


我厌倦了用 gdb 调试,无效的指针地址是 p_lines 向量的起始地址。 gdb 框架指向函数的 las 。 如何解决 free(): invalid pointer 错误以及导致分段错误的问题。 来自 gdb 的错误消息:

    glibc detected *** /home/xyz: free(): invalid pointer: 0x080cc482 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x12fe591]
    /lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0x12ffde8]
    /lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0x1302ecd]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x11fa741]
    /home/xyz(_Z19Probabilistic_HoughN2cv3MatERS0_+0x8c5)[0x804b3b5]
    /home/xyz(_Z13imageCallbackRKN5boost10shared_ptrIKN11sensor_msgs6Image_ISaIvEEEEE+0x5c8)[0x804b9a0][0x804b3b5]
/home/xyz(_Z13imageCallbackRKN5boost10shared_ptrIKN11sensor_msgs6Image_ISaIvEEEEE+0x5c8)[0x804b9a0]

并且 p_lines 的打印是(_M_start = 0x80cc482 等于 free(): i. p. :0x080cc482):

(gdb) p p_lines
$1 = <std::_Vector_base<cv::Vec<int, 4>, std::allocator<cv::Vec<int, 4> > >> = 
    _M_impl = <std::allocator<cv::Vec<int, 4> >> = <__gnu_cxx::new_allocator<cv::Vec<int, 4> >> = <No data fields>, <No data fields>, _M_start = 0x80cc482, _M_finish = 0x80cc540, 
      _M_end_of_storage = 0x80cc540, <No data fields>

我在纠正我的错字后重新做了一些测试,并在最后添加了一个if (countP&gt;0)。找到出现无效指针操作的帧,img有12个p_lines和2个filt_lines,但是countP=0(所以两条线相交超出了img大小)。 gdb 显示调用HoughLinesP()p_lines 的起始地址为_M_start = 0x80d4e70,崩溃后free(): i.p. 出现在0x080d4e71 和我的函数中gdb frame p_lines 的起始地址是_M_start = 0x80d4e71。 什么鬼?向量的起始地址怎么可能随着1位的变化而变化?

我终于找到了p_lines 发生位变化的确切时刻:

(gdb) next
    98                      imgGrid[int(crosP.x/sizeX)][int(crosP.y/sizeY)]++;
    (gdb) p p_lines 
    $68 = <std::_Vector_base<cv::Vec<int, 4>, std::allocator<cv::Vec<int, 4> > >> = 
        _M_impl = <std::allocator<cv::Vec<int, 4> >> = <__gnu_cxx::new_allocator<cv::Vec<int, 4> >> = <No data fields>, <No data fields>, 
          _M_start = 0x80d4c78, _M_finish = 0x80d4d38, _M_end_of_storage = 0x80d4d38, <No data fields>
    (gdb) next
    84              for (size_t j=i+1;j<filt_lines.size();j++)
    (gdb) p p_lines 
    $69 = <std::_Vector_base<cv::Vec<int, 4>, std::allocator<cv::Vec<int, 4> > >> = 
        _M_impl = <std::allocator<cv::Vec<int, 4> >> = <__gnu_cxx::new_allocator<cv::Vec<int, 4> >> = <No data fields>, <No data fields>, 
          _M_start = 0x80d4c79, _M_finish = 0x80d4d38, _M_end_of_storage = 0x80d4d38, <No data fields>
(gdb) p j
$71 = 1

所以在这种情况下,filt_lines 的大小为 2。并且 位移 出现在检查第一行和第二行之后,当 j=1 时跳转回for j

【问题讨论】:

我的猜测是这次通话中发生了一些不好的事情:HoughLinesP( src, p_lines, 1, CV_PI/180, 85, 40, 10 ); 在通话前后检查 p_lines。 这在代码审查时可能会做得更好;要么把它变成一个最小的测试用例,也许.. 我在 'HoughLinesP( src, p_lines, 1, CV_PI/180, 85, 40, 10 );' 之前检查了 p_lines在它之后,并且在错误出现之后。我在上面的问题中添加的结果。 【参考方案1】:

您在最内层循环中的filt_lines 向量上有索引溢出。我想应该是

 for (size_t j = i + 1; j < filt_lines.size(); j++)

而不是

 for (size_t j=i+1;j<p_lines.size();j++)

【讨论】:

谢谢,这是我的错字之一。但我仍然有同样的错误...... @user1899326 请复制并粘贴您正在编译的确切代码,而不是输入它。 好的,我复制了,你想要那个洞码吗?

以上是关于free():vector <vec4i> c ++的无效指针[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

基于比例法和颜色筛选的面积计算

Opencv 的各个vector容器探究

Opencv 的各个vector容器探究

寻找最小矩形边框--OpenCv

Opencv 计算图片旋转角度

Opencv 发现轮廓 findContours