分段错误,以前在使用GNU编译时不存在,现在使用Clang

时间:2016-11-18 18:22:17

标签: c++ segmentation-fault g++ clang

所以我读到的是,clang是一个更严格的标准实施,但这个真的让我感到困惑......

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

希望我提供了足够的信息。我对clang完全不熟悉,在谷歌搜索和搜索之后我从来没有遇到任何问题我仍然迷失了......

1 个答案:

答案 0 :(得分:1)

正如Basile Starynkevitch正确指出的那样,您的计划展示了undefined behavior

展示此类行为的程序可以任何。这包括出现以便在使用一个编译器编译时正常工作,而在使用另一个编译器(或使用不同的优化级别或针对不同平台)编译时崩溃。

这样的程序也可能看起来行为不规律,例如在随机位置崩溃,或者当某些部分被注释掉时会出现不同的崩溃。

可以从此代码段中猜出第一个(但绝不是唯一的)未定义行为的实例:

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

我们可以从您的输出中猜测inputFileName具有值"inputFileMavericAftCGApproachFlapsDown.dat",这需要42个字符存储在数组中,并且您将该值复制到32字节缓冲区中,从而导致堆栈溢出(这是产生未定义行为的众多方法之一)。

顺便说一下,这个副本完全没有意义,没有用处。你应该通过const引用而不是值传递inputFileName

那么,你应该怎么做?

  1. 找一位对CC++有所了解的有能力的导师,你真的需要一个。
  2. 阅读Basile建议的文档。
  3. 使用Address Sanitizer编译代码(由Clang和GCC支持)。如果能找到这个特殊的bug,以及Basile在评论中指出的那个,可能还有更多。
  4. 修复了地址清理程序发现的所有错误后,请转到Memory Sanitizer以获取更多错误。
  5. 在您的程序清洁剂清洁后,它将有更好的正常工作机会,但仍然无法确保无错误。