2016-11-18 76 views
-2

所以我想讀取鐺是一個很大的嚴格的標準執行力度,但是這一次我百思不得其解......段錯誤,以前不是有當GNU編譯,現在用鏘

void readInputFile(const string inputFileName, Geometry &planeGeom, FlightConditions &FC, AircraftChar & aeroChar, 
vector<string> &runFileResults, int &vorlaxRun, int &lateralTrue) 
{ 
    int inputRuns; 
    char infile[32], blank, cTest[32], iTest[32]; 
    char aircraftInpFile[80]; 
    char vorlaxCommand[80]; 
    string casTest, inpTest; 
    double S_ref,span,Cbar,Xbar,Zbar,St_ref,mac_t,Sf_ref,CD_0,Mach,Uinf,rho; 
    FILE *ofpInput; 

    strcpy(infile,inputFileName.c_str()); 
    ofpInput = fopen(infile, "r"); 
    assert(ofpInput!=NULL); 

    fscanf(ofpInput, "%i", &lateralTrue); //0--false only longitudinal analysis, 1--true long and lateral 
    printf("lateralTrue = %i\n",lateralTrue); 

    fscanf(ofpInput, "%i", &vorlaxRun); //0--false will input aero data, 1--true will input run files and execute vorlax 
    printf("Are we running Vorlax? -- %i\n",vorlaxRun); 

    fscanf(ofpInput, "%i", &inputRuns);    //for looping to run all the needed vorlax files 
    printf("inputRuns = %i\n",inputRuns); 
    runFileResults.resize(2*inputRuns); 

    cout << "I made it to the part where I am reading" << vorlaxRun << "\n" << endl; 

    fscanf(ofpInput, "%s", &blank); //reading in data from input file 
    fscanf(ofpInput, "%lf %s", &planeGeom.S, &blank); 
    fscanf(ofpInput, "%lf %s", &planeGeom.b, &blank); 
    fscanf(ofpInput, "%lf %s", &planeGeom.cBar, &blank); 
    fscanf(ofpInput, "%lf %s", &planeGeom.xBar, &blank); 
    fscanf(ofpInput, "%lf %s", &planeGeom.zBar, &blank); 
    fscanf(ofpInput, "%lf %s", &planeGeom.St, &blank); 
    fscanf(ofpInput, "%lf %s", &planeGeom.mact, &blank); 
    fscanf(ofpInput, "%lf %s", &planeGeom.Sf, &blank); 
    fscanf(ofpInput, "%lf %s", &aeroChar.CD_0, &blank); 
    fscanf(ofpInput, "%lf %s", &aeroChar.e, &blank); 
    fscanf(ofpInput, "%lf %s", &FC.mach, &blank); 
    fscanf(ofpInput, "%lf %s", &FC.uinf, &blank); 
    fscanf(ofpInput, "%lf %s", &FC.rho, &blank); 
    fscanf(ofpInput, "%lf %s", &FC.alpha, &blank); 
    fscanf(ofpInput, "%lf %s", &aeroChar.dEdA, &blank); 

    cout << "I made it past reading all the planeGeom stuff " << vorlaxRun << "\n" << endl; 

    //Commented out code section for debugging purposes... 

    cout << "I made it past reading all the aeroChar stuff" << "\n" << endl; 

所以它似乎int vorlaxRun引起的問題很奇怪,所以我將它添加到了我的印刷品中(如上所見)以查看發生了什麼,這是我得到的輸出結果。

Reading inputFileMavericAftCGApproachFlapsDown.dat 
lateralTrue = 0 
Are we running Vorlax? -- 0 
inputRuns = 0 
I made it to the part where I am reading0 

Segmentation fault: 11 

如果我拿出vorlaxRun的第二個實例正在打印,這是我所得到的

Reading inputFileMavericAftCGApproachFlapsDown.dat 
lateralTrue = 0 
Are we running Vorlax? -- 0 
inputRuns = 0 
I made it to the part where I am reading0 

I made it past reading all the planeGeom stuff 

I made it past reading all the aeroChar stuff 

Abort trap: 6 

我想我會想到中止陷阱6,因爲我不得不註釋掉在一堆線看到發生了什麼的過程。但我不明白爲什麼刪除打印變量到屏幕上的第二個實例導致它神奇的工作......爲什麼,如果我將其添加在最後COUT然後我得到這樣的:

Reading inputFileMavericAftCGApproachFlapsDown.dat 
lateralTrue = 0 
Are we running Vorlax? -- 0 
inputRuns = 0 
I made it to the part where I am reading0 

I made it past reading all the planeGeom stuff 

Segmentation fault: 11 

希望我提供了足夠的信息。我完全陌生的叮噹,我從來沒有任何問題,在谷歌搜索後,我仍然失去了這個+ ...

+1

你爲什麼要將C代碼與C++混合? –

+0

編譯所有警告和調試信息(例如'g ++ -Wall -g'或'clang -Wall -g')。我沒有讀你的代碼,但我想你有一些[未定義的行爲](https://en.wikipedia.org/wiki/Undefined_behavior)。使用'gdb'調試器 –

+0

'fscanf(ofpInput,「%s」,&blank);'很可能是[未定義行爲](https://en.wikipedia.org/wiki/Undefined_behavior) –

回答

1

正如巴西爾Starynkevitch正確指出,您的程序展品undefined behavior

展示此類行爲的程序可以做任何事情。這包括出現在使用一個編譯器進行編譯時正常工作,而在與另一個編譯器(或使用不同優化級別或不同平臺)編譯時發生崩潰。

這樣的程序也可能表現出不正常的行爲,例如在隨機地方崩潰,或者當它的某些部分被註釋掉時以不同的方式崩潰。

第一(但絕不是唯一的)的未定義行爲實例可以從這個代碼片段猜測:

char infile[32], ...; 
strcpy(infile,inputFileName.c_str()); 

我們可以從你的輸出inputFileName具有價值"inputFileMavericAftCGApproachFlapsDown.dat",這就需要猜測42個字符存儲在一個數組中,並且您將該值複製到一個32字節的緩衝區中,從而導致堆棧溢出(這是導致未定義行爲的多種方法之一)。

順便說一下,該副本是完全沒有意義的,並沒有任何用處。你應該通過inputFileName通過const引用而不是按值。

那麼,你應該怎麼做?

  1. 找到一個能夠導師誰知道一些關於CC++,你真的需要一個。
  2. 按照Basile建議閱讀文檔。
  3. Address Sanitizer編譯你的代碼(由Clang和GCC支持)。如果能找到這個特殊的錯誤,以及Basile在評論中指出的錯誤,可能還有更多。
  4. 一旦您修復了Address Sanitizer發現的所有錯誤,請繼續閱讀Memory Sanitizer瞭解更多錯誤。

在您的程序清理乾淨後,它將有更好的正常工作機會,但仍然無法保證無缺陷。

+0

非常感謝您指出我「真的需要」一名C++導師。這是幾年前的舊代碼,我試圖用最小的努力來恢復,像這樣的評論在學習環境中是不明顯的和不必要的。是的,我使用地址清理工具進行了編譯,並沒有幫助我爲什麼在這裏發佈,實際上我得到的調試信息指向了變量vorlaxRun。 – spacegirl1923

相關問題