2016-04-23 47 views
0

所以,我试图将一些代码带到我正在开发的Qt项目中。 Motion类使用fstream将.txt文件中的一些控制点导入公共成员变量ctrlPos。例如,当我使用readCtrlPositions,然后尝试使用writePositions访问ctrlPos时,出现“矢量下标超出范围”错误。为什么这个代码访问向量超出了它的范围?

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

运动类的头:

#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 

Motion类:

其中Qt中程序出现错误
#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() 
{ 

} 

样品的编号:

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

你检查了numberOfPositions是否等于ctrlPos.size()或不? – jpo38

+0

DualQuaternion是否有有效的拷贝构造函数? – jpo38

回答

0

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

稍后,您将尝试访问0numberOfPositions(非零)的ctrlPos元素,而ctrlPos向量为空。这就是为什么你被报告访问矢量超出其范围!

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

我还强烈建议您删除您的numberOfPositions属性,并简单地使用ctrlPos.size()来代替。在这种情况下,它可以防止崩溃,保证您的类属性完整。

+0

解决了这个问题。谢谢。我会ctrlPos.size()而不是numberOfPositions,但输入文件更改大小。 – Dan

+0

它改变了numberOfPositions和ctrlPos.size()。分别维护这两个变量是没有意义的 – jpo38

+0

因此,当我第一次从.txt文件导入数据时,我不知道文件中有多少个点。如果我没有'numberOfPositions',我不知道迭代'inFile >> RotationQuaternion [i];',inFile >> TranslationVector [i];'或'inFile >> TranslationQuaternion [i] ;'。在导入点之前''ctrlPos.size()'与'numberOfPositions'不是同一个值。 – Dan