繁体   English   中英

push_back()中的分段错误

[英]Segmentation Fault in push_back()

我在push_back()中遇到分段错误,我在下面给出了我的项目的示例代码。 我不在vec内使用image(IplImage *),因为我在push_back()之后清除了温度(IplImage *)

我的疑问是,我应该更换...

a.cands.push_back(b);

...与...

 b.frontImg = NULL;
 a.cands.push_back(b);

...?

该程序:

#include<iostream>
#include<vector>
#include<highgui.h>
#include<cv.h>

using namespace std;

struct B
{
  IplImage* frontImg;
  vector<int> num;
  B()
  {
    frontImg = NULL;
  }
}; 

struct A
{
  vector<B> cands;
  IplImage* img1;
  A()
  {
    img1 = NULL;
  }
};

vector<A> vec;

int main()
{
  for (int i = 0; i < 1000; i++)
  {
    struct B b;
    IplImage* temp = cvLoadImage("logo.jpg");
    b.frontImg = temp;

    struct A a;

    for (int j = 0; j<1000; j++)
    {
      a.cands.push_back(b);
    }

    vec.push_back(a); //here

    cvReleaseImage(&temp);

    //some porcess
  }
}

来自评论的错误信息

 #0 0x000000353a0328a5 in raise () from /lib64/libc.so.6  
 #1 0x000000353a034085 in abort () from /lib64/libc.so.6  
 #2 0x000000353a0707b7 in __libc_message () from /lib64/libc.so.6  
 #3 0x000000353a0760e6 in malloc_printerr () from /lib64/libc.so.6  
 #4 0x000000353a079b64 in _int_malloc () from /lib64/libc.so.6  
 #5 0x000000353a07a911 in malloc () from /lib64/libc.so.6  
 #6 0x0000000000688a7d in operator new(unsigned long)  
 #7 ???  
 #8 0x0000000000563fdd in std::_Vector_base<CvPoint, std::allocator<CvPoint> >::_M_allocate (this=0x7f31ad14bb90, __n= 1096) at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_ve‌​ctor.h:140  
 #9 0x0000000000560491 in std::_Vector_base<CvPoint, std::allocator<CvPoint> >::_Vector_base (this=0x7f31ad14bb90, __n= 1096, __a=...) at /usr/lib/gcux/4.4.7./include/c++/4.4.7/bits/stl_vector.h:113  
 #10 0055ebc1 in std::vector<CvPoint, std::allocator<CvPoint> >::vector (this=0x7f31ad14bb90, __x= std::vector of length 1096, capacity 1096 = {../include/c++/  
 #11 ???  
 #12 ???  
 #13 ???  
 #14 0x000000000055f346 in std::vector<LPCandidate, std::allocator<LPCandidate> >::push_back (this=0x7f31ac00ddb0, __x= ...) at /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_ve‌​ctor.h:737  
 #15 0x0000000000556689 in KLPR::TrManager::segregateLane (this=0x7f31ac0008e8, candLPV= std::vector of length 6, capacity 32 = {...}, candIndex=0x7f31b3ffd500) at MyProject/src/TrManager.cpp:2026  

发布的代码看起来很危险

  • 原始指针
  • 没有析构函数/复制构造函数/赋值运算符(规则3(C ++ 03),规则5(C ++ 11)
  • 没有明确的数据所有权。
  • 删除后可能使用的数据。
  • 缺少检查clLoadImage是否失败。

看评论:

struct B b;
IplImage* temp = cvLoadImage("logo.jpg");
b.frontImg = temp;

struct A a;

for (int j = 0; j<1000; j++)
  a.cands.push_back(b);

现在您有1000个元素指向b.frontImg返回的图像,我假设您在实际程序中为每个b.frontImg加载了不同的图像。

vec.push_back(a); //here

A的默认拷贝构造函数被调用,如果a不再使用a的默认析构函数调用,删除所有B S IN的矢量。 在所示的程序部分中,没有任何一个有问题。

cvReleaseImage(&temp);

现在,您也释放了这1000个元素所指向的内容(如果使用b.frontImg ,那么如果b.frontImg不使用b.frontImg也不是问题。

//some process

在这里,您希望不要通过B中的指针使用刚发布的图像。


现在您的问题,是的,您应该使用

b.frontImg = NULL;
a.cands.push_back(b);

因为它消除了许多问题,所以现在没有人可以通过b复制或删除图像(如果您记得以后要删除图像)。


添加一个原始指针如何危险的示例

~B() { delete frontImg; } // or some user of B decides to delete frontImg itself.

代码,但没有复制构造函数或复制赋值运算符。 现在每次你做一个

a.cands.push_back(b);  // implicit copy construct of a new b.

b在超出范围时会被销毁。 您可以有效地推回b ,该b将指向已删除的图像,而当删除a时,您将通过向量的b再次删除该图像,从而破坏了堆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM