1

I am programming a Genetic Algorithm for a research task. I am not a very experienced C++ programmer (since I am a mathematician), but I managed my program to compile and run correctly using MSVC 2008 and g++ compilers on a Windows environment (I used CygWin to run g++ on Windows 7). Now, the problem is that this program have to run in a cluster computer that uses g++ on a Linux environment, but it always crashes in execution time (though at least it compiles correctly). I have addressed the obvious details (as using / instead of \ for file names), but could not make it run properly on Linux.

However, when I comment the function 'Cruce' below, the program ends, though it obviously does not perform the required tasks. This is the code of such a function, together with other functions called by it (the only global variable is BITGEN, it is an integer with value 30 used for Gray code translation of floating point numbers):

    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;  

        }
    }
}

I have tried my best for days in order to find the possible error but it was in vain. I guess the error has to be related with a memory issue (as I always get a Segmentation Fault error), but I could not figure where it is. There should be a critical difference between the ways Windows and Linux process memory that I am not aware of. Any of you could help me?

Thanks in advance!

5
  • I think you should attempt to narrow down where it could be exiting. It's hard to tell what's going on here, and your use of calloc could cause you issues in the long run, depending on how much data you're asking for and how often. The stack is not infinite and behaves different per platform. Commented Oct 20, 2012 at 0:28
  • @John: in fact, I guess the problem has to be related with the resizing of the POPULATION and CONTROL vector variables via the push_back() member, since the program crashes on other functions outside 'Cruce' that however does not give problems when these variables remains their size... Commented Oct 20, 2012 at 0:52
  • 1
    Can you show the code that is calling the Cruce function? Commented Oct 20, 2012 at 21:29
  • 1
    run your application under Linux using valgrind, this tools will tell you what's your doing wrong. Commented Oct 21, 2012 at 13:30
  • another problem is long is a 32-bit type in Windows but 64-bit type in Linux Commented Apr 22, 2015 at 17:32

2 Answers 2

2

Some general tips that might help you:

  • compile with the -Wall -Wextra options to g++ and improve your source code till all warnings are gone

  • try also compiling with clang++ compiler also with -Wall (or similar) option

  • compile with the -g options (in addition of -Wall) to get debugging information

  • use gdb to debug your program (and run the program under the debugger, then use bt for backtracing, etc...)

  • use valgrind to find memory leaks

  • avoid using calloc and malloc, better use standard C++ containers (like std::string, std::vector<>, std::map<> etc.).

Also, install a Linux distribution on your own laptop or desktop and learn to use Linux thru the command line.

Sign up to request clarification or add additional context in comments.

3 Comments

I would suggest installing a Linux distro through something like Virtualbox, which allows you to share the source code on both platforms and test both at the same time.
With a native linux distro, you can have e.g. your /home on a separate Ext3 partition and share it with Windows using fs-driver.org
That would still require very frequent rebooting, where a VM can coexist with the host OS.
2

I'm seeing a potential error in the presented code.

    static char *tmpstring;
    static int flag = 1;

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

What's happening if the function StringRep() is called multiple times with a growing genes argument : the buffer won't be growing and thus, someone is going to write outside of the first buffer allocated. Note, the same apply to function Cruce().

Then I think there's a second error regarding fin=TAMPOP;. There's no explanation of what is TAMOP. But are you not going outside of an array when doing POPULATION[fin+1], CONTROL[fin+1][0]=1; or fin=fin+2;.

Regards.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.