空vector< Point>Size()在循环条件下会导致奇怪的行为



我得到一些奇怪的行为,我不明白,也许我只是错过了一些明显的东西。我希望有人能解释一下。

下面是一些导致问题的代码:

#include <stdio.h>
#include <tchar.h>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
// draw line from point to point along the point "list"
void drawLineSegments(Mat img, vector<Point> points, Scalar colour = Scalar(255,255,255)){
    for (int i = 0; i < (points.size()-1); i ++){
        line(img,points[i],points[i+1], colour);
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    Mat testImg = Mat(100,100,CV_8U,0.0); // test black image, not important
    vector<Point> testPoints; // new vector
    drawLineSegments(testImg,testPoints); // try to draw it, expect function to do nothing because size should be 0
    return 0;
}

这个编译但是在运行时给出一个错误"vector下标超出范围",通过调试我可以看到这是因为for循环运行。为什么要运行for循环?这就是我不明白的地方。

调用testPoints.size()似乎返回0,如果我改变绘制函数:

// draw line from point to point along the point "list"
void drawLineSegments(Mat img, vector<Point> points, Scalar colour = Scalar(255,255,255)){
    int lengthMinusOne = points.size()-1;
    for (int i = 0; i < lengthMinusOne; i ++){
        line(img,points[i],points[i+1], colour);
    }
}

那就行了。那么为什么不能在条件中直接使用points。size()呢?

这一行是罪魁祸首。

for (int i = 0; i < (points.size()-1); i ++){

具体来说,(points.size()-1)

这相当于说:

size_t s = points.size(); // Which is zero for you use case.
s = s - 1;  // This is not -1. It's large positive number.
for (int i = 0; i < s; i ++){

由于s != -1,您将在for循环中输入代码块并从points访问成员,这将导致未定义的行为。

您应该已经看到关于有符号/无符号比较的警告(for循环有缺陷)。

size()返回一个size_t,它是无符号的,从零减去1会导致下流。当你对int进行赋值时,它会在循环中正确地将其设置为-1,你实际上是在将UINT_MAX与i进行比较。

相关内容

  • 没有找到相关文章

最新更新