2016-04-23 48 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