2012-10-20 65 views
1

我正在爲一項研究任務編寫遺傳算法。我不是一個非常有經驗的C++程序員(因爲我是數學家),但是我管理我的程序在Windows環境下使用MSVC 2008和g ++編譯器進行編譯和運行(我使用CygWin在Windows 7上運行g ++)。現在,問題是這個程序必須在Linux環境中使用g ++的集羣計算機上運行,​​但它總是在執行時崩潰(儘管至少它編譯正確)。我已經解決了明顯的細節(如使用/而不是\用於文件名),但無法使其在Linux上正常運行。我的程序在Windows上運行MSVC和g ++編譯器,但在Linux上不運行

但是,當我評論下面的函數'Cruce'時,程序結束,但它顯然不執行所需的任務。這是這樣一個函數的代碼,連同由它稱爲其它功能(全球唯一的變量是BITGEN,它是與用於浮點數的格雷碼變換值30的整數):

void xPC_BLX(double d, const vector<double>& P1, const vector<double>& P2, 
    vector<double>& Hijo1, vector<double>& Hijo2, int genes){ 

    double I, A1, C1; 
    int i; 

    for (i=0; i < genes; i++) 
    { 

     I= d * fabs(P1[i]-P2[i]); 

     A1=P1[i]-I; if (A1<0) A1=0.0; 
     C1=P1[i]+I; if (C1>1) C1=1.0; 
     Hijo1[i]= A1 + Rand()*(C1-A1); 

     A1=P2[i]-I; if (A1<0) A1=0.0; 
     C1=P2[i]+I; if (C1>1) C1=1.0; 
     Hijo2[i]= A1 + Rand()*(C1-A1); 
     } 
    } 

/**********************************************************/ 
/* Itoc and Ctoi translate ints to strings and vice versa */ 
/**********************************************************/ 
    unsigned long int Ctoi(char *Cad_ent, int length){ 

     int i;  
    unsigned long n;  

    n = (unsigned long) 0; 
    for (i=0; i<length; i++) 
    { 
     n <<= 1; 
     n += (*Cad_ent++ - (int) '0'); 
    } 
    return(n); 
    } 

    void Itoc(unsigned long int n, char *Cad_sal, int length){ 

     int i;  

     for (i=length-1; i>=0; i--) 
     { 
      Cad_sal[i] = (char)('0' + (n & 1)); 
      n >>= 1; 
     } 
    } 


/*****************************************************************/ 
/* Translations between fixed point ints and reflected Gray code */ 
/*****************************************************************/ 

    void Gray(char *Cad_ent, char *Cad_sal, int length){ 

     int i; 
     char last; 

     last = '0'; 
     for (i=0; i<length; i++) 
     { 
     Cad_sal[i] = (char)('0' + (Cad_ent[i] != last)); 
     last = Cad_ent[i]; 
     } 
    } 

/*************************************************************************/ 
/* Translations between string representation and floating point vectors */ 
/*************************************************************************/ 
    void StringRep(const vector<double> vect, char *Cad_sal, int genes){ 

     int i; 
     unsigned long int n; 
     int pos; 
     double INCREMENTO; 
     static char *tmpstring; 
     static int flag = 1; 

     if (flag) { 
     tmpstring = (char*) calloc (genes*BITGEN,sizeof(char)); 
     flag = 0; 
     } 

     pos = 0; 
     for (i=0; i < genes; i++) 
     { 

     INCREMENTO=(1-0)/(pow(2.0, (double) BITGEN) - 1.0); 

     n = (int) ((vect[i] - 0)/INCREMENTO + 0.5); 

     Itoc(n, tmpstring, BITGEN); 
     Gray(tmpstring, &Cad_sal[pos], BITGEN); 

     pos += BITGEN; 
     } 
     Cad_sal[pos] = '\0'; 

    } 

/*****************************************/ 
    int DistHam(char *Cr_1, char *Cr_2, int genes){ 

     int i, dist; 
     dist=0; 

     for (i=0; i<genes*BITGEN; i++) if (Cr_1[i]!=Cr_2[i]) dist++; 

     return dist ; 
    } 

/**********************/ 
/* CROSS OPERATOR */ 
/**********************/ 

    void Cruce(int& fin, int genes, vector<vector<double> >& POPULATION, 
     vector<vector<double> >& CONTROL, double GA_THR) 
    { 

     int i, j, temp, mom, dad; 
     static char *String1, *String2; 
     static int flag=1; 
     vector<double> newind(genes+1,0), newcont(2,0); 


     if (flag) { 
     String1 = (char*) calloc (genes*BITGEN,sizeof(char)); 
     String2 = (char*) calloc (genes*BITGEN,sizeof(char)); 
     flag = 0; 
     } 

     vector<int> sample(TAMPOP,0); 
     for (i=0; i < TAMPOP; i++) sample[i] = i; 

    for (i=0; i < TAMPOP; i++) 
    { 
     j = Randint(i,TAMPOP-1); 
     temp = sample[j]; 
     sample[j] = sample[i]; 
     sample[i] = temp; 
    } 

    for (i=0; i < TAMPOP; i++) CONTROL[i][0]=0; 

    fin=TAMPOP; 

    for (i=0; i < TAMPOP/2; i++) 
    { 
     mom=sample[2*i]; 
     dad=sample[2*i+1]; 


     StringRep(POPULATION[mom], String1, genes); 
     StringRep(POPULATION[dad], String2, genes); 


     if (DistHam(String1, String2, genes)/2.0 > GA_THR) 
     { 

      POPULATION.push_back(newind); 

      POPULATION.push_back(newind); 

      CONTROL.push_back(newcont); 

      CONTROL.push_back(newcont); 

      xPC_BLX(1,POPULATION[mom],POPULATION[dad],POPULATION[fin], 
       POPULATION[fin+1], genes); 

      CONTROL[fin][0]=1; 
      CONTROL[fin+1][0]=1; 
      fin=fin+2; 

     } 
    } 
} 

我爲了找到可能的錯誤而努力了幾天,但這是徒勞的。我想這個錯誤必須與內存問題有關(因爲我總是遇到Segmentation Fault錯誤),但我無法確定它在哪裏。 Windows和Linux處理內存的方式之間應該存在關鍵差異,我不知道。你們中的任何人都可以幫助我?

在此先感謝!

+0

我認爲你應該嘗試縮小它可能退出的位置。很難說出這裏發生了什麼,並且從長遠來看,使用calloc可能會導致您遇到問題,具體取決於您請求的數據量和頻率。堆棧不是無限的,每個平臺的行爲都不相同。 –

+0

@John:實際上,我猜這個問題必須與通過push_back()成員調整POPULATION和CONTROL矢量變量的大小有關,因爲程序在'Cruce'之外的其他函數上崩潰,但是當這些變量保持其大小... – tingo

+1

你可以顯示調用Cruce函數的代碼嗎? –

回答

2

一些通用的技巧,可以幫助你:

  • -Wall -Wextra選項編譯爲g++和改善你的源代碼,直到所有的警告都不見了

  • 嘗試也clang++編譯器編譯還與-Wall (或類似的)選項

  • 編譯-g選項(除了-Wall)來獲取調試信息

  • 使用gdb調試程序(和調試器下運行該程序,然後使用bt的回溯,等...)

  • 使用valgrind查找內存泄漏

  • 避免使用callocmalloc,更好地使用標準C++容器(如std::string,std::vector<>,std::map<>等)。

另外,在您自己的筆記本電腦或臺式機上安裝Linux發行版,並通過命令行學習使用Linux。

+0

我建議通過像Virtualbox這樣的東西來安裝Linux發行版,它允許您在兩個平臺上共享源代碼並在同一時間。 – rubenvb

+0

使用本地Linux發行版,您可以使用例如你的'/ home'放在一個單獨的Ext3分區上,並使用http://www.fs-driver.org/ –

+0

與Windows共享。這仍然需要*非常頻繁的重新啓動,其中虛擬機可以與主機操作系統共存。 – rubenvb

2

我在提供的代碼中看到了一個潛在的錯誤。

static char *tmpstring; 
    static int flag = 1; 

    if (flag) { 
     tmpstring = (char*) calloc (genes*BITGEN,sizeof(char)); 
     flag = 0; 
    } 

發生了什麼事,如果功能StringRep()與越來越genes參數多次調用:緩衝區將不會增長,因此,有人會寫外面分配的第一緩衝區。請注意,同樣適用於功能Cruce()

然後我認爲有關於fin=TAMPOP;的第二個錯誤。沒有解釋什麼是TAMOP。但是在做POPULATION[fin+1]CONTROL[fin+1][0]=1;fin=fin+2;時,你不打算排隊。

問候。

相關問題