Link to home
Start Free TrialLog in
Avatar of Gordy1984
Gordy1984Flag for United Kingdom of Great Britain and Northern Ireland

asked on

URGENT: Require guidance fixing bug in C++ project developed in Borland C++ Builder 6.0

Hi,
I am developing an Excel addin for a university project and have come up against a brick wall.

I am in the process of writing code that solves discrete optimisation problems defined as spreadsheets in Excel. One part of the iterative process involved in this addin is to add solutions to an archive.

The following method performs this...

        void CWSCALL colony::updateParetoSet()
        /* Manages the Pareto set.
         * 1) Checks to see if Pareto set is empty, if so all rank 1 non-dominated
         *    solutions are added to the archive
         * 2) Reviews all rank 1 non-dominated ants within population to see if
         *    they all eligible to be stored in the archive. If so, the solutions
         *    it dominates are removed from the Pareto set.
         * 3) Calculates crowding distance of each solution in Pareto set.
         * 4) Performs pareto set pheromone update
         */
        {
                bool check;
                ant tmp;
                bool add;
                int removeCount;
                int tmpParetoSize = 0;
                int k = 0;
                ant *tmpPareto;
                ShowMessage(paretoSize);
                if (paretoSize == 0) {
                    for (int i = 0; i < config->population_size; i++) {
                                //ShowMessage(ants[i].getParetoRank());
                                if (ants[i].getParetoRank() == 1) {
                                        paretoSize++;
                                }
                    }
                    pareto = new ant[paretoSize];
                    k = 0;
                    for (int i = 0; i < config->population_size; i++) {
                                if (ants[i].getParetoRank() == 1) {
                                        pareto[k] = ant(ants[i]);
                                        k++;
                                }
                    }
                } else {
                    for (int i = 0; i < config->population_size; i++)
                    {
                                ShowMessage(i); // Test output
                                if (ants[i].getParetoRank() == 1) {
                                        check = true;
                                        for (int j = 0; j < paretoSize; j++)
                                        {
                                                if (dominatedBy(ants[i], pareto[j])) {
 >>                                                       ShowMessage("dominated");
 >>                                                       check = false;
                                                }
                                        }
                                        if (check) {
                                                removeCount = 0;
                                                for (int j = 0; j < paretoSize; j++)
                                                {
                                                        if (dominatedBy(pareto[j], ants[i])){
                                                                removeCount++;
                                                        }
                                                }
                                                tmpParetoSize = (paretoSize - removeCount) + 1;
                                                tmpPareto = new ant[tmpParetoSize];
                                                k = 0;
                                                for (int j = 0; j < paretoSize; j++)
                                                {
                                                        if (!dominatedBy(pareto[j], ants[i])){
                                                                tmpPareto[k] = ant(pareto[j]);
                                                                k++;
                                                        }
                                                }
                                                tmpPareto[k] = ant(ants[i]);
                                                paretoSize = tmpParetoSize;
                                                pareto = new ant[paretoSize];
                                                for (int j = 0; j < paretoSize; j++)
                                                {
                                                        pareto[k] = ant(pareto[j]);
                                                }
                                                delete[] tmpPareto;
                                        }
                                }
                    }
                }
                CWSFLOAT hold;
                Objective obj = config->getObjective(0);
                CWSINTEGER rank;
                CWSFLOAT crowd;
                for (int j = 0; j < paretoSize; j++)
                /* Reset current crowding distance values */
                {
                        pareto[j].setCrowdingDistance(0);
                }
                for (int i = 0; i < config->no_objectives; i++)
                {
                        sortParetoSet(pareto, 0, paretoSize-1,i);
                        for (int j = 0; j < paretoSize; j++)
                        {
                              if (j == 0 || j == paretoSize-1) {
                                crowd = 1000; // LARGE NUMBER
                              } else {
                                crowd =  pareto[j].getCrowdingDistance();
                                crowd += pareto[j-1].getSolutionQuality(i) - pareto[j+1].getSolutionQuality(i);
                              }
                              pareto[j].setCrowdingDistance(crowd);
                        }
                }

        }

The problem I am having is a runtime issue  and occurs within the main else section of the method. Basically, an empty pareto set is succesfully populated. Then, after the next iteration when the method is called the latter part of the method is called, the else part. The specific error produces an Access violation and occurs around the area labelled with ">>" in the code snippet.

To my knowledge this isnt a normal problem and I have spent ages trying to fix it but I just cannot see the cause of the problem. Could anyone give me any pointers?

Thanks
Avatar of jkr
jkr
Flag of Germany image

What are the values of 'config->population_size' and 'paretoSize' when the crash happens? Looks like you are trying to access array elements that are out of bounds.
Avatar of Gordy1984

ASKER

I have just checked this a few times and in each case neither are zero when the access violation occurs.

It may be important to note that this access violation occurs after one succesful loop where check boolean is true, and therefore elements are removed from the paretoSet.

It may also be important that error happsn after a breakpoint that is placed on the following line...

if (dominatedBy(ants[i], pareto[j])) {

Could there be any other cause of the problem?
What is the code for the function that is called?
I believe the error is caused by something in this method. I have checked to see if config->no_objectives is ever set to zero but this is not the case, it stays as a constant, as expected.  Can anyone see any problems here? thanks.

        bool CWSCALL colony::dominatedBy(ant &a, ant &b)
        /* Checks to see if ant a is dominated by ant b */
        {
                Objective obj;
                int a1;
                int b1;
                int obj_count = 0;
                ShowMessage(config->no_objectives);
                for (int ii = 0; ii < config->no_objectives; ii++)
                {
                      obj = config->getObjective(ii);
                      a1 = a.getSolutionQuality(ii);
                      b1 = b.getSolutionQuality(ii);
                      if (obj.isBetter(b1,a1)) {
                        obj_count++;
                      }
                }
                if (obj_count == config->no_objectives) {
                        return true;
                } else {
                        return false;
                }
        }
All of the working calls to
   ShowMessage()
are being passed an integer value.  The failing one is being passed the address of a C-style string literal.  Since the error occurs on that particular line, then that might be the problem.
ASKER CERTIFIED SOLUTION
Avatar of George Tokas
George Tokas
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It will be interesting to know where the bug was...
Can you please tell us?

George Tokas.