2010-08-26 37 views
1

今天我遇到一個奇怪的問題。我的C++代碼可以在調試模式下工作。 使用g ++ -g編譯代碼。但是,當我使用g ++ -O來優化代碼。它會卡住某處。看起來有死循環。有誰知道如何找到這種錯誤?當我用DDD debuger調試代碼時,它工作正常。謝謝!如何找到G ++優化C++代碼的錯誤?

代碼的一部分(我找到這部分就被卡住)下方粘貼:

void Solver::reduceRoutes() 
{ 
    int V=pinst->get_V(); //get the given number of vehicles 
    if(int(curSol_.size())<=V) // return when solution has no extra routes 
     return; 

    int routeNum1,routeNum2; // the two routes modified 

    listSize=int(0.2*pinst->get_N()); 

    short TheNode,anode;   // the second node 
    float totalInc;    //the obj increase of a candidate position 
    Route::iterator it; 
    vector<short> candidateList; 
    vector<short> validCandidateList; //nodes can be moved to 
    vector<float> totalImpList; 
    int solSize=int(curSol_.size()); 

    while(solSize>V) 
    { 
     // cout <<"debug6.0 "; 
     routeNum1=psol->findRouteWithMinC(curSol_); 
     cout <<" debug6.1 "<<curSol_.size()<<" "<<routeNum1; 
     while(curSol_[routeNum1].size()>2) 
     { 
      it=curSol_[routeNum1].begin(); 
      it++; 
      TheNode=*it; 
      candidateList=pinst->get_PNL(TheNode,listSize); 

      // evaluate the effect of moving the node to each possible position 

      for(unsigned int i=1;i<candidateList.size();i++)  //the first node is itself 
      { 
       anode=candidateList[i]; 

       routeNum2=RouteNumList[anode]; //find the route of second node 
       if(routeNum2!=routeNum1)   //inter route move 
       { 
        totalInc=evaluateAreduceRouteMove(curSol_,routeNum1,routeNum2,TheNode,anode); 
        totalImpList.push_back(totalInc); 
        validCandidateList.push_back(anode); 
       } 
      } 

      //find the best position to insert the 
      int ii=(min_element(totalImpList.begin(),totalImpList.end())-totalImpList.begin()); 
      anode=validCandidateList[ii]; 

      it=find(curSol_[routeNum1].begin(),curSol_[routeNum1].end(),TheNode); 
      curSol_[routeNum1].erase(it);  //remove from route1 

      routeNum2=RouteNumList[anode]; 
      it=find(curSol_[routeNum2].begin(),curSol_[routeNum2].end(),anode); 
      ++it; 
      curSol_[routeNum2].insert(it,TheNode); //insert to the second route 
      RouteNumList[TheNode]=routeNum2;  //update route number 
      //improve the modified routes 

      psol->doTwoOpt(curSol_[routeNum2]); 
      totalImpList.clear(); 
      validCandidateList.clear(); 
     } 

     //update route number list 
     for(unsigned int i=routeNum1+1;i<curSol_.size();i++) 
     { 
      for(it=curSol_[i].begin();it!=curSol_[i].end();it++) 
       RouteNumList[*it]-=1; 

     } 

     RouteNumList[0]=0; 
     // eliminate the empty route 
     curSol_.erase(curSol_.begin()+routeNum1); 
     solSize=curSol_.size(); 
     cout <<" debug6.3 "<<solSize<< " \n"; 

    } 

    return; 
} 

感謝您回答我的問題。現在我的代碼沒有進行優化。我只是想知道優化器做了什麼,因此代碼工作。如果優化模式不能提高速度,那麼可以不使用它。任何人都可以評論優化模式的力量嗎? 再次感謝。

+0

請將您的所有代碼縮進四個空格,它會將其放入一個代碼塊中。 – Jasper 2010-08-26 20:26:29

+1

開始的提示:爲了可讀性分解爲不同的功能。聲明它們時初始化所有變量。不要重複使用同一個變量來實現多種目的。使用已檢查的STL版本運行,以確保您不會在迭代器指向已修改的容器時發生錯誤(常見問題) – 2010-08-26 20:36:36

+0

@Greg:同意。當它不回答問題時,只接受任何垃圾作爲答案是沒有意義的。 – 2010-09-01 17:06:07

回答

2

爲什麼在循環開始時,您將solSize指定爲int int solSize=int(curSol_.size());,但在while循環solSize=curSol_.size();中沒有這樣做。您可能想要調查調試和優化版本中的值。

另外,似乎有代碼中的浮動/雙打被比較(可能是)整數的地方。可能是這是無限循環的原因。

+0

有規則將浮點類型與整數類型進行比較。這裏的危險是浮點值可能不準確,所以比較(特別是任何相等比較)可能會稍微偏離。 – 2010-08-26 20:39:57

1

你怎麼知道這是你掛的地方?是來自printf/cout調試嗎?如果是這樣,你就走在正確的軌道上。在這些情況下,這可能是一個強大的工具。

我同意Gangadhar,檢查你的類型。如果您指定其他優化級別,它是否仍然掛起?如果關閉優化並且不包含調試符號(沒有-O或-g選項)會怎麼樣?

+0

是的,我將cout添加到了幾個位置,發現代碼在這裏停止。 它沒有掛沒有-O。實際上,我已經用一個實例進行了測試,當CurSol.size()= 197時,它就被打斷了。現在我只是不知道如何找到它被卡住的地方。 – Jackie 2010-08-26 21:01:19

2

除非遇到編譯器錯誤(並且我每十年的命中次數少於1次),問題是您的代碼沒有完全定義的行爲,並且正在以調試模式編譯一種方式另一種優化方式。編寫優化器的人通常不會對未定義或未指定的行爲負責;如果代碼錯誤,輸出也是如此。

您是否嘗試過啓用所有可能的警告?他們中的一些人可能會給你一些有關錯誤的信息。快速瀏覽一下你所包含的代碼並不代表對我有任何建議。

您的程序中的其他地方也可能存在未定義的行爲,很可能是堆損壞。搞清楚總是很有趣。

1

您可能可以使用幾個電話pstack來找出程序在循環時的位置。如果無法獲得滿意的結果,您最好的選擇是cout s ...很多cout s,在函數的每個點內都精確地縮小了它掛起的位置。沒有這些信息,我們只是猜測盲目。編譯-Wall並確保沒有任何警告。

1

要做的第一件事就是確保所有的代碼編譯乾淨。
大部分這些類型的錯誤都會導致您使用(不知情)某些未定義的行爲或意外地做了一些愚蠢的事情。編譯器會警告你大部分這些情況,所以你可以利用這個優勢。

添加以下內容:

-ansi -pedantic -W -Wall -Werror

這將迫使你解決所有的簡單的問題。

1

我發現了錯誤。來自浮點型變量比較的問題。由於精度,比較造成無限循環。謝謝你們。 你真的很有幫助。