为什么此代码访问其范围之外的向量?

时间:2016-04-23 21:58:20

标签: c++ qt stl

所以,我正在尝试将一些代码带到我正在研究的Qt项目中。 Motion类使用fstream将.txt文件中的一些控制点导入公共成员变量ctrlPos。当我使用readCtrlPositions,然后尝试使用ctrlPos访问writePositions时,我收到错误“向量下标超出范围”。

还有更多代码,但希望这足以回答我的问题。我也是一个新手,所以运气好的话不是太愚蠢。

动作类标题:

#ifndef MOTION_H
#define MOTION_H

#include <vector>

#include "DualQuaternion.h"

class Motion
{
public:
    virtual ~Motion();
    virtual void readCtrlPositions(char*, char*);
    virtual void writePositions(char*);
    virtual void drawCtrlPositions();
    virtual void set(int, vector<DualQuaternion>);
    virtual pair<int, vector<DualQuaternion>> get();

public:
    vector<DualQuaternion> ctrlPos, c;
    int numberOfPositions;

};

#endif

动作类:

#include <stdlib.h>
#include <GL\glut.h>

#include "motion.h"
#include "Quaternion.h"
#include "hMatrix.h"
#include "hPoint.h"

using namespace std;

void Motion::readCtrlPositions(char *fileNameArg, char *t)
{
    ifstream inFile(fileNameArg, ios::in);

    if (!inFile)
    {
        cerr<<"File" << fileNameArg << "could not be opened" << endl;
        exit(1);
    }

    int i;

    inFile >> numberOfPositions;

    Quaternion *RotationQuaternion = new Quaternion[numberOfPositions];

    for (i = 0; i<numberOfPositions; i++)
        inFile >> RotationQuaternion[i];

    if (t == "v")
    {
        Vector *TranslationVector = new Vector[numberOfPositions];
        for (i = 0; i<numberOfPositions; i++)
            inFile >> TranslationVector[i];
        ctrlPos.clear();
        for (i = 0; i<numberOfPositions; i++)
        {
            DualQuaternion dQ(RotationQuaternion[i], TranslationVector[i]);
            ctrlPos.push_back(dQ);
            cout << "first position from input: " << ctrlPos[i] << endl;
        }
        delete[] TranslationVector;
    }
    else if (t == "q")
    {
        Quaternion *TranslationQuaternion = new Quaternion[numberOfPositions];
        for (i = 0; i<numberOfPositions; i++)
            inFile >> TranslationQuaternion[i];
        ctrlPos.clear();
        for (i = 0; i<numberOfPositions; i++)
        {
            DualQuaternion dQ(RotationQuaternion[i], TranslationQuaternion[i]);
            ctrlPos.push_back(dQ);
            cout << "first position from input: " << ctrlPos[i] << endl;
        }
        delete[] TranslationQuaternion;
    }

    delete[] RotationQuaternion;

}

void Motion::writePositions(char *fileNameArg)
{
    ofstream outFile(fileNameArg, ios::out);

    if (!outFile)
    {
        cerr<<"File" << fileNameArg << "could not be opened for writing" << endl;
        exit(1);
    }

    int i;

    outFile << numberOfPositions << endl << endl;

    for (i = 0; i<numberOfPositions; i++)
        outFile << ctrlPos[i].GetReal();
    outFile << endl;
    for (i = 0; i<numberOfPositions; i++)
        outFile << ctrlPos[i].GetDual();
}

void Motion::set(int n, vector<DualQuaternion> p)
{
    int i;
    numberOfPositions = n;
    ctrlPos.clear();
    for (i = 0; i<numberOfPositions; i++)
        ctrlPos.push_back(p[i]);
}

pair<int, vector<DualQuaternion>> Motion::get()
{
    return make_pair(numberOfPositions, ctrlPos);
}

void Motion::drawCtrlPositions()
{

    vector <hMatrix> homogeneousMatricesForCtrlPositions;
    for (int i=0; i<numberOfPositions; i++)
    {
        homogeneousMatricesForCtrlPositions.push_back(ctrlPos[i].dualQuaternionToHomogeneousMatrix().transpose());
        double MatrixforOpenGLStack[16];

        for (int i1=0; i1<4; i1++)
            for (int i2=0; i2<4; i2++)
                MatrixforOpenGLStack[4*i1+i2] =  homogeneousMatricesForCtrlPositions.at(i).m[i1][i2];

        ::glPushMatrix();
        ::glMultMatrixd(MatrixforOpenGLStack);
        glutSolidTeapot(0.15);
        ::glPopMatrix();
    }

}

Motion::~Motion()
{

}

Qt程序中出现错误的示例代码:

static Curve m;
m.readCtrlPositions("input.txt", "v");
m.writePositions("output.txt"); //<--vector subscript out of range
m.readCtrlPositions("output.txt", "q");
ctrlPos = m.get().second;
numberOfPositions = m.get().first;

1 个答案:

答案 0 :(得分:0)

readCtrlPositions中,tchar*,因此t=="v"t=="q"也不会被评估为true(它会返回true如果两个指针具有相同的地址)。因此,您的函数会将numberOfPositions设置为非零值,但永远不会将ctrlPos向量填充为任何值。

稍后,您将尝试访问从ctrlPos0的{​​{1}}元素(非零),而numberOfPositions向量为空。这就是为什么你被报告访问其范围之外的向量!

ctrlPos替换为char*是解决问题的简便方法。如果您需要将参数保留为std::string,请使用char*来比较字符串值而不是指针。

我还强烈建议您删除strcmp属性,然后只使用numberOfPositions。通过保证您的类属性完整性,它可以防止在这种情况下发生崩溃。