用std::vector编写可调整大小的矢量时出现问题

  • 本文关键字:问题 vector std 可调整 c++
  • 更新时间 :
  • 英文 :


我是c++编码的巴西初学者(很抱歉我在这两方面都不太了解)。我正在尝试写一个.txt输出文件,其中包含我用鼠标点击的像素位置。我正在使用opencv库,所以这是代码的一个功能部分:

#include "opencv2/highgui/highgui.hpp"
#include <iostream>    
#include <vector> 
#include <fstream>    
using namespace std;
using namespace cv;
//declaration of vector and counter
int i = 1;
std::vector<int>vet_x(i);
std::vector<int>vet_y(i);

//the callback function
void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
    if (event == EVENT_LBUTTONDOWN)
    {
        vet_x.resize(i);
        vet_y.resize(i);
        vet_x[i] = x;
        vet_y[i] = y;
        i++;
        cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << endl;
    }
}
int main(int argc, char** argv)
{
    Mat img = imread("lena.jpg");
    //Create a window
    namedWindow("Mouse Track Test", 1);
    //set the callback function for mouse event
    setMouseCallback("Mouse Track Test", CallBackFunc, NULL);
    //show the image
    imshow("Mouse Track Test", img);
    // Wait until user press some key
    waitKey(0);
    //the writing begins after the press of the key
    ofstream myfile;
    myfile.open("points.txt");
    for (int j = 1; j <= vet_x.size(); j++)
    {
        cout << vet_x[j] << "," << vet_y[j] << endl;
        myfile << vet_x[j] << "," << vet_y[j] << endl;
    }
    myfile.close();
    return 0;
}

问题是:文件只写最后点击的位置!但如果我转动"vet_x.reserve(1024);"线,它工作得很好,但只适用于y坐标。。。

那么,我的错误是什么?

C++数组索引是基于0的。因此,当将向量v的大小调整为1,并指定给v[1]时,就等于指定给了不存在的项。这是未定义的行为。

要捕获这种越界索引,可以使用at方法,它可以保证出现异常。即写v.at(i)而不是v[i]

但是,您应该简单地使用push_back成员函数将项添加到向量中。即v.push_back( x ),其中x是要添加的值。使用2D点的单个向量也可能是一个好主意,而不是一个向量用于x和一个向量。

vet_x.resize(i);
vet_y.resize(i);
vet_x[i]=x;
vet_y[i]=y;

您分配的元素超出范围,这是一种未定义的行为。在resize(i)之后,最后一个有效索引是i-1。std::vector运算符[]从不在容器中插入元素。

而只是做

vet_x.push_back(x);
vet_y.push_back(y);

将变量添加到向量中的方法是错误的。我建议这样做:

struct Point
{
    int x, y;
    Point(int sx, int sy)
        :x(sx),y(sy)
    {        
    }
};
std::vector<Point> clickedPositions;
//the callback function
void CallBackFunc(int event, int x, int y, int flags, void* userdata)
{
    if  ( event == EVENT_LBUTTONDOWN )
    {
        clickedPositions.push_back(Point(x,y));
    }
}

并且在将其写入文件时:

for(int j=0; j<clickedPositions.size(); j++)
  {   
   myfile << clickedPositions[j].x < <","<< clickedPositions[j].y <<endl;
  }