向量的指针问题
我在尝试将自定义类的对象 Push_back 到以我的自定义类作为类型的指针向量时遇到了相当大的麻烦。 请参阅下面的代码以及收到的错误。 我在 Windows XP 上使用带有 CDT 插件的 Eclipse 和 OpenCV。
我花了很多时间试图找到答案但毫无结果! PS我是一名学生,指针等不是我的事!
std:: vector<RoadLine>* LaneChangeDetector::roadLines(IplImage* img_8uc1, IplImage* img_8uc3, IplImage* img_edge, std::vector <RoadLine>* roadVector){
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines = 0;
CvMemStorage* roadStorage = cvCreateMemStorage(0);
CvSeq* roadLines = 0;
// Probabalistic Hough transform returns line segments from edge detected image
lines = cvHoughLines2( img_edge, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 200, 200 );
// Sequence roadlines, lines with correct slope are added to this sequence
roadLines = cvCreateSeq(0, lines->header_size, lines->elem_size, roadStorage);
// slope
double m = 0.0;
// Point of intersection
CvPoint poi;
for(int i = 0; i < lines->total; i++ ){
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
CvPoint pt1 = line[0];
CvPoint pt2 = line[1];
double x1 = double(pt1.x);
double y1 = double(pt1.y);
double x2 = double(pt2.x);
double y2 = double(pt2.y);
if(pt1.x == pt2.x){
m = 1.0;
}
else{
m = (double(y2 - y1)/(double(x2 - x1)));
}
if( ((m>0.45) && (m<0.75)) || ((m<-0.45) && (m>-0.75)) ){
// If the slope is between measured parameters add to roadLines sequence for further analysis
cvSeqPush(roadLines, line);
}
}
// otherRoadLine used for comparison
CvPoint* otherRoadLine;
for(int a=0; a<roadLines->total; a++){
CvPoint* roadLine = (CvPoint*)cvGetSeqElem(roadLines,a);
CvPoint rl1 = roadLine[0];
CvPoint rl2 = roadLine[1];
int lineCount = 0;
if(a>0){
// Test the current line against all the previous lines in the sequence.
// If the current line is far enough away from all other lines then draw it
for(int b=0; b<a; b++){
otherRoadLine = (CvPoint*)cvGetSeqElem(roadLines,b);
if((roadLine->x > ((otherRoadLine->x) + 200)) || (roadLine->x < ((otherRoadLine->x) - 200)) ){
lineCount++;
}
}
if(lineCount == a){
cvLine(img_final, roadLine[0], roadLine[1], CV_RGB(0,0,255), 3, CV_AA, 0 );
RoadLine myLine = RoadLine(roadLine, 1);
roadVector->push_back(myLine); //ERROR OCCURS HERE
cvShowImage("Plate Detection", img_final);
cvWaitKey(0);
}
}
else{
cvLine(img_final, roadLine[0], roadLine[1], CV_RGB(0,0,255), 3, CV_AA, 0 );
RoadLine myLine = RoadLine(roadLine, 1);
roadVector->push_back(myLine //ERROR OCCURS HERE
cvShowImage("Plate Detection", img_final);
cvWaitKey(0);
}
}
if(roadVector->size() >= 2){
int pos = 0;
RoadLine line1 = roadVector->at(pos);
RoadLine line2 = roadVector->at(pos + 1);
CvPoint* A = line1.line;
CvPoint p1 = A[0];
CvPoint p2 = A[1];
int A1 = p1.y - p2.y;
int B1 = p1.x - p2.x;
int C1 = (p1.x*p2.y) - (p1.y*p2.x);
CvPoint* B = line2.line;
CvPoint p3 = B[0];
CvPoint p4 = B[1];
int A2 = p3.y - p4.y;
int B2 = p3.x - p4.x;
int C2 = (p3.x*p4.y) - (p3.y*p4.x);
int det = A2*B1 - A1*B2;
if(det == 0){
printf("Lines are parallel");
}
else{
int x = ( C1*(p3.x - p4.x) - (p1.x - p2.x)*C2 )/det;
int y = ( C1*(p3.y - p4.y) - (p1.y - p2.y)*C2 )/det;
poi.x = x;
poi.y = y;
horizon = poi.x;
cvCircle(img_final, poi, 10, CV_RGB(255, 0, 0), 2, CV_AA, 0);
}
}
cvShowImage("Plate Detection", img_final);
cvWaitKey(0);
return roadVector;
}
可以在此处看到自定义类 RoadLine
#include <cv.h>
class RoadLine{
private:
CvPoint* line;
int lane;
public:
RoadLine(CvPoint*, int);
};
RoadLine::RoadLine(CvPoint* aLine, int aLane){
line = aLine;
lane = aLane;
}
从调试中我可以看到“std::vector
以下是 Eclipse 告诉我的内容:
3 std::vector<RoadLine, std::allocator<RoadLine> >::push_back() F:\MinGW\include\c++\3.4.5\bits\stl_vector.h:560 0x0043e3f9
4 void std::_Construct<RoadLine, RoadLine>() F:\MinGW\include\c++\3.4.5\bits\stl_construct.h:81 0x0044015d
程序跳转到 stl_construct.h 中的这部分代码
template<typename _T1, typename _T2>
inline void
_Construct(_T1* __p, const _T2& __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_]allocator::construct
::new(static_cast<void*>(__p)) _T1(__value); //DEBUG THROWS ME TO THIS LINE
}
再次,任何帮助将不胜感激。
干杯
帕特
I am having quite a bit of trouble with trying to push_back an object of my custom class to a vector of pointers with my custom class as the type. Please see the code below along with the error received. I am using Eclipse with the CDT plugin and OpenCV on windows xp.
I have spent so much time trying to find an answer but to no avail!
ps I am a student and pointers etc are not my thing!
std:: vector<RoadLine>* LaneChangeDetector::roadLines(IplImage* img_8uc1, IplImage* img_8uc3, IplImage* img_edge, std::vector <RoadLine>* roadVector){
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* lines = 0;
CvMemStorage* roadStorage = cvCreateMemStorage(0);
CvSeq* roadLines = 0;
// Probabalistic Hough transform returns line segments from edge detected image
lines = cvHoughLines2( img_edge, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 200, 200 );
// Sequence roadlines, lines with correct slope are added to this sequence
roadLines = cvCreateSeq(0, lines->header_size, lines->elem_size, roadStorage);
// slope
double m = 0.0;
// Point of intersection
CvPoint poi;
for(int i = 0; i < lines->total; i++ ){
CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
CvPoint pt1 = line[0];
CvPoint pt2 = line[1];
double x1 = double(pt1.x);
double y1 = double(pt1.y);
double x2 = double(pt2.x);
double y2 = double(pt2.y);
if(pt1.x == pt2.x){
m = 1.0;
}
else{
m = (double(y2 - y1)/(double(x2 - x1)));
}
if( ((m>0.45) && (m<0.75)) || ((m<-0.45) && (m>-0.75)) ){
// If the slope is between measured parameters add to roadLines sequence for further analysis
cvSeqPush(roadLines, line);
}
}
// otherRoadLine used for comparison
CvPoint* otherRoadLine;
for(int a=0; a<roadLines->total; a++){
CvPoint* roadLine = (CvPoint*)cvGetSeqElem(roadLines,a);
CvPoint rl1 = roadLine[0];
CvPoint rl2 = roadLine[1];
int lineCount = 0;
if(a>0){
// Test the current line against all the previous lines in the sequence.
// If the current line is far enough away from all other lines then draw it
for(int b=0; b<a; b++){
otherRoadLine = (CvPoint*)cvGetSeqElem(roadLines,b);
if((roadLine->x > ((otherRoadLine->x) + 200)) || (roadLine->x < ((otherRoadLine->x) - 200)) ){
lineCount++;
}
}
if(lineCount == a){
cvLine(img_final, roadLine[0], roadLine[1], CV_RGB(0,0,255), 3, CV_AA, 0 );
RoadLine myLine = RoadLine(roadLine, 1);
roadVector->push_back(myLine); //ERROR OCCURS HERE
cvShowImage("Plate Detection", img_final);
cvWaitKey(0);
}
}
else{
cvLine(img_final, roadLine[0], roadLine[1], CV_RGB(0,0,255), 3, CV_AA, 0 );
RoadLine myLine = RoadLine(roadLine, 1);
roadVector->push_back(myLine //ERROR OCCURS HERE
cvShowImage("Plate Detection", img_final);
cvWaitKey(0);
}
}
if(roadVector->size() >= 2){
int pos = 0;
RoadLine line1 = roadVector->at(pos);
RoadLine line2 = roadVector->at(pos + 1);
CvPoint* A = line1.line;
CvPoint p1 = A[0];
CvPoint p2 = A[1];
int A1 = p1.y - p2.y;
int B1 = p1.x - p2.x;
int C1 = (p1.x*p2.y) - (p1.y*p2.x);
CvPoint* B = line2.line;
CvPoint p3 = B[0];
CvPoint p4 = B[1];
int A2 = p3.y - p4.y;
int B2 = p3.x - p4.x;
int C2 = (p3.x*p4.y) - (p3.y*p4.x);
int det = A2*B1 - A1*B2;
if(det == 0){
printf("Lines are parallel");
}
else{
int x = ( C1*(p3.x - p4.x) - (p1.x - p2.x)*C2 )/det;
int y = ( C1*(p3.y - p4.y) - (p1.y - p2.y)*C2 )/det;
poi.x = x;
poi.y = y;
horizon = poi.x;
cvCircle(img_final, poi, 10, CV_RGB(255, 0, 0), 2, CV_AA, 0);
}
}
cvShowImage("Plate Detection", img_final);
cvWaitKey(0);
return roadVector;
}
The custom class RoadLine can be seen here
#include <cv.h>
class RoadLine{
private:
CvPoint* line;
int lane;
public:
RoadLine(CvPoint*, int);
};
RoadLine::RoadLine(CvPoint* aLine, int aLane){
line = aLine;
lane = aLane;
}
From debugging i can see that "std::vector <RoadLine>* roadVector" is being intialised correctly.
Here is what Eclipse tells me:
3 std::vector<RoadLine, std::allocator<RoadLine> >::push_back() F:\MinGW\include\c++\3.4.5\bits\stl_vector.h:560 0x0043e3f9
4 void std::_Construct<RoadLine, RoadLine>() F:\MinGW\include\c++\3.4.5\bits\stl_construct.h:81 0x0044015d
And the program jumps to this section of code in stl_construct.h
template<typename _T1, typename _T2>
inline void
_Construct(_T1* __p, const _T2& __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_]allocator::construct
::new(static_cast<void*>(__p)) _T1(__value); //DEBUG THROWS ME TO THIS LINE
}
Again any help would be greatly appreciated.
Cheers
Pat
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您不使用指针向量,而是使用对象向量。 在这种情况下,您的类需要有一个复制构造函数,因为 Push_back 存储对象的副本。
作为一般的调试建议,尝试通过删除尽可能多的代码来解决问题,但仍然会看到不正确的行为。 尝试找到失败的最简单的例子。
You do not use vector of pointers, but vector of objects. In that case, your class needs to have a copy constructor, as push_back stores a copy of object.
As a general debugging advice, try to boil down the problem by removing as much code as you can and still see incorrect behaviour. Try to find the simplest example that fails.
你的新 RoadLine 类肯定会导致灾难:
使用它的代码:
“myLine”的自动销毁将删除“myLine.line”(在 RoadLine 的 dtor 中)
但向量中仍然引用“myLine.line”(您刚刚推送了它)。
您必须对行进行深度复制(正如其他人建议的那样),如下所示:
或者使用 CvLine 对象而不是指针(或其他东西,需要更多上下文)
编辑:
Dirk Gently 的 copy-ctor 有一个 bug,因为它会将内存泄漏给前一个“line”成员
应该是:
编辑2:我几乎忘记了我知道为什么它会崩溃! 也许你尝试用最后一个和最后一个+1 CvPoint 构建一对(就像这个明显错误的代码)?
Your new RoadLine class will certainly lead to disaster :
code using it :
the automatic destruction of "myLine" will delete "myLine.line" (in RoadLine's dtor)
but "myLine.line" is still referenced in the vector (you just pushed it).
You have to either make a DEEP COPY of line (as others suggested), something like this :
Or use a CvLine object rather than a pointer (or something else, need more context)
EDIT :
Dirk Gently's copy-ctorhas a bug, because it leaks memory to the former "line"-member
should be :
EDIT 2 : I almost forgot that I had an idea why it crashes ! maybe you try to build a pair with last and last+1 CvPoint (like this obviously false code)?
您的 RoadLine 类缺少适当的复制因子。 现在,由于您有一个指向
CvPoint
对象的成员,因此您每次push_back
时都会创建指针的副本。 这可能是不可取的。缩短代码:尝试隔离问题:
这会崩溃吗?
Your
RoadLine
class lacks a proper copy-ctor. Now, since you have a member that points to aCvPoint
object you have create a copy of the pointer every time youpush_back
. This is probably not desirable.Shorten your code: Try to isolate the problem:
Does this crash?
C++ 的技巧是把“~”键想象成又大又红,只要你按下它,闹钟就会响起,即。 每当您考虑向类添加析构函数时。
如果您要添加析构函数,那么您需要一个复制构造函数和赋值运算符。 没有例外。 即使您不打算复制该对象,您仍然应该在私有部分中声明它们,这样如果意外使用它们,编译器就会给出错误。
当对象的生命周期受到控制时,您还应该使用引用计数指针而不是原始 C 风格指针(在 C++ 中,这是“RAII”)。 如果你这样做,析构函数将从 RoadLine 中消失,神奇的是,你的问题也会消失。
The trick with C++ is to imagine the "~" key as big and red and that alarm bells will sound whenever you press it, ie. whenever you're thinking of adding a destructor to a class.
If you're adding a destructor then you NEED a copy constructor and assignment operator. No exceptions. Even if you're not going to copy the object you should still declare them in the private section so the compiler will give errors if they're used accidentally.
You should also use a reference counted pointer instead of a raw C-style pointer whenever the lifetime of an object is being controlled (in C++-speak this is "RAII"). If you did this the destructor would vanish from RoadLine, and, magically, so would your problem.
你没有指针向量。
是指向 RoadLine 对象向量的指针。 如果您想要一个指针向量,您应该这样做:
这可能会对您有所帮助(因为向量将不再调用复制构造函数),但您仍然应该按照其他人的建议对它们进行排序。
You don't have a vector of pointers.
is a pointer to a vector of RoadLine objects. If you want a vector of pointers, you should do:
That may help you (since the vector won't be invoking copy constructors any more), but you should still look at sorting those out as others have suggested.
此类错误通常是由不正确的内存管理引起的。 遗憾的是,您还没有发布如何管理记忆的方法。
如果你可以让它在 Linux 系统上运行,你可以尝试在 valgrind 下运行你的程序,这有助于追踪不正确的内存访问/释放。 不幸的是,valgrind 在 windows 下不可用,但可能有替代品。
These kinds of errors are usually caused by incorrect memory-management. Sadly, you haven't posted the way how do you manage your memory.
If you can get it run on a linux system, you can try running your program under valgrind, which helps to track down incorrect memory accesses/freeing. Unfortunately, valgrind is not available under windows, but there may be substitutes.
我已将 RoadLine 的类定义更改为:
这是 RoadLine 类的当前版本
这就是我实现该类的方式:
当调用 push_back 时,它会调用复制构造函数,但程序在上面突出显示的地方崩溃了
有什么区别事实上我的向量已定义;
我有一个 CvPoint* 而不是 CvPoint[]
抱歉,如果这些看起来非常基本的问题
i have changed my class definition of RoadLine to:
This is the current version of the RoadLine class
This is how I am implementing the class:
When push_back is called it calls the copy constructor but the program crashes where highlighted above
What difference is made by the fact that my vector is defined;
and that i have a CvPoint* not CvPoint[]
sorry if these seem very basic questions