Problem with pointers

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • DumRat
    New Member
    • Mar 2007
    • 93

    Problem with pointers

    Hello,
    I am making this TSP solver using a genetic algorithm. And I ran into this problem and I can't work it out. The problem is, I pass the two parent genes and the two child genes into the crossover function and then the crossover function is supposed to allocate memory for the child genes and fill them accordingly. But after the function has finished, the two child genes are NULL. I debugged and found out that inside the crossover function they are allocated separate memory and are filled out accordingly. But when the function returns, they become NULL. I am using a static function. Is this in someway to be blamed? But I tried changing it into a regular member function and still the same problem occurs. I' d be very glad if anyone can help. I am providing the relevant code below. Thanks.


    Code:
    static void Crossover(CGene & parent1, CGene & parent2, CGene * child1, CGene * child2)
    	{
                   child1 = new CGene(parent1);
    	       child2 = new CGene(parent2);
                   
                   double doCrossover = Random((double)0.0f, (double)CROSSOVER_RATE);
    
    		//Perform crossover CROSSOVER_RATE% of the time
    		if(doCrossover < CROSSOVER_RATE)
    		{
    			//Partially Matched Crossover
    //--------------------------------------------------------------------
    			int low, high;								//Two crossover points
    			low = Random(0, GENE_LENGTH);
    			high = Random(0, GENE_LENGTH);
    
    			if(low > high)
    			{
    				int temp = low;
    				low = high;
    				high = temp;
    			}
    
    			int * temp = new int[high - low];
    
    			//Actual crossover in the range [low, high)
    			for(int i = low; i < high; i++)
    			{
    				temp[i - low] = child1->gene[i];
    			}
    			for(i = low; i < high; i++)
    			{
    				child1->gene[i] = child2->gene[i];
    			}
    			for(i = low; i < high; i++)
    			{
    				child2->gene[i] = temp[i - low];
    			}
    
    			//Perform the rehabilitation here
    	    
    		}
    	}


    Code:
    CGene(const CGene & gene)
    	{
    		this->gene = new int[GENE_LENGTH];
    		for(int i = 0; i < GENE_LENGTH; i++)
    		{
    			this->gene[i] = gene.gene[i];
    		}
    		this->fitness = gene.fitness;
    		this->cost = gene.cost;
    	}
  • DumRat
    New Member
    • Mar 2007
    • 93

    #2
    Can anyone plz help?

    Comment

    • xoinki
      New Member
      • Apr 2007
      • 110

      #3
      hi,
      Static Functions are generally used as wrappers.. its strange that u have used this way.. My suggestion would be.. just use more private variables.. and put all the code you have written inside a private function.. declare an object of the class in the static function and then call the private function you have written from the static function and see..

      Regards,
      Xoinki

      Comment

      • smalpani
        New Member
        • Aug 2007
        • 29

        #4
        1. Are you sure this is correct crossover logic, you ar enot using parent at all.

        2. See the trouble is you are passing the child pointers be value so whatever change in the address of child pointer value you willmake wills tay local to function. So you will have to pass a pointer to pointer to child so that the change is available with the returned function.


        So what exactly are you doing with GA. GA is cool GA is fantastic I have done lot of work with it.

        Comment

        • JosAH
          Recognized Expert MVP
          • Mar 2007
          • 11453

          #5
          Make both child1 and child2 references to CGene pointers. Now you're using a
          pass by value mechanism that can't affect any of the pointers outside your
          function. You want to set two (other) CGene pointers to a value instead.

          The C 'equivalent' (mind the quotes) would be to pass pointers to pointers of
          CGene objects but that is so C-ish.

          kind regards,

          Jos

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Originally posted by DumRat
            Code:
            static void Crossover(CGene & parent1, CGene & parent2, CGene * child1, CGene * child2)
            	{
            // <snipped, not relevent to the problem>
            	}
            You have declared you function incorrectly.

            Think of it this way if you wanted a function to pass an int back in a parameter you would declare it as taking a pointer to an int and pass the address of an int to the function

            Code:
            void Function(int *number)
            {
                *number = 10;
            }
            
            int main()
            {
                int myInt;
            
                Function(&myInt);
            
               return 0;
            }
            If you wanted a function to pass a double back in a parameter you would declare it as taking a pointer to a double and pass the address of a double to the function

            Code:
            void Function(double *number)
            {
                *number = 10.1;
            }
            
            int main()
            {
                double myDouble;
            
                Function(&myDouble);
            
               return 0;
            }
            In the general case for any type T if you wanted a function to pass a T back in a parameter you would declare it as taking a pointer to a T and pass the address of a T to the function

            Code:
            typedef <SomeType> T;
            
            void Function(T *number)
            {
                *number = T(10);
            }
            
            int main()
            {
                T myT;
            
                Function(&myT);
            
               return 0;
            }
            In your example the type of the variable you are trying to pass back is CGene *, there fore T = CGene * and in order to pass a CGene * back through a parameter the function needs to declare the parameter type as CGene **.

            Your function prototype should be

            [CODE=cpp]
            static void Crossover(CGene & parent1, CGene & parent2, CGene ** child1, CGene ** child2)
            {
            // <snipped, not relevent to the problem>
            }
            [/CODE]

            Comment

            • Banfa
              Recognized Expert Expert
              • Feb 2006
              • 9067

              #7
              Originally posted by JosAH
              Make both child1 and child2 references to CGene pointers. Now you're using a
              pass by value mechanism that can't affect any of the pointers outside your
              function. You want to set two (other) CGene pointers to a value instead.
              Damn piped to the post, BTW in a reference to a pointer which way round do the * and & come?

              Comment

              • DumRat
                New Member
                • Mar 2007
                • 93

                #8
                Hey, thanks!
                However, later I got the same problem again with deleting a pointer.
                Taking your advice, I was able to solve the first problem.
                But I could not delete an object by deleting the pointer passed to the outside by a function. The delete keyword did not clear any memory. I tried all the tricks you told to use here. Passing by reference, pointer to pointers, etc.
                Is there something about delete that causes this abnormal behaviour? Or is it me just implementing badly?
                Anyway, I got the solution to my first problem. Thanks

                Comment

                • DumRat
                  New Member
                  • Mar 2007
                  • 93

                  #9
                  Originally posted by smalpani
                  1. Are you sure this is correct crossover logic, you ar enot using parent at all.

                  2. See the trouble is you are passing the child pointers be value so whatever change in the address of child pointer value you willmake wills tay local to function. So you will have to pass a pointer to pointer to child so that the change is available with the returned function.


                  So what exactly are you doing with GA. GA is cool GA is fantastic I have done lot of work with it.

                  I was doing this for a TSP solver. I love(not literally) GAs too though I do not know too much about them. Glad to find another GA enthusiast!
                  I got to know about GAs from this very good article. And I've used them on couple of occasions. Not for real problems. Just for fun.

                  http://www.ai-junkie.com/ga/intro/gat1.html

                  Comment

                  • JosAH
                    Recognized Expert MVP
                    • Mar 2007
                    • 11453

                    #10
                    Originally posted by Banfa
                    Damn piped to the post, BTW in a reference to a pointer which way round do the * and & come?
                    If T& is a reference to a T then a CGene*& is a reference to a CGene*.
                    A CGene&* would be a pointer to a reference of a CGene.

                    kind regards,

                    Jos

                    Comment

                    • Banfa
                      Recognized Expert Expert
                      • Feb 2006
                      • 9067

                      #11
                      Originally posted by JosAH
                      If T& is a reference to a T then a CGene*& is a reference to a CGene*.
                      A CGene&* would be a pointer to a reference of a CGene.
                      That is what I figured I just wanted to check :D

                      Comment

                      • Banfa
                        Recognized Expert Expert
                        • Feb 2006
                        • 9067

                        #12
                        Originally posted by DumRat
                        Hey, thanks!
                        However, later I got the same problem again with deleting a pointer.
                        Taking your advice, I was able to solve the first problem.
                        But I could not delete an object by deleting the pointer passed to the outside by a function. The delete keyword did not clear any memory. I tried all the tricks you told to use here. Passing by reference, pointer to pointers, etc.
                        Is there something about delete that causes this abnormal behaviour? Or is it me just implementing badly?
                        Anyway, I got the solution to my first problem. Thanks
                        The delete keyword does not clear any memory, it returns the memory that was allocated from the heap to the heap. No memory contents are necessaryily changed

                        This code will print out the same 2 values, delete does not change the contents of the variable holding the pointer, if you want it to change (to NULL say) then you need to do it yourself.
                        [code=cpp]
                        int *pint = new int;

                        cout << reinterpret_cas t<unsigned long>(pint) << endl;

                        delete pint;

                        cout << reinterpret_cas t<unsigned long>(pint) << endl;
                        [/code]

                        Comment

                        Working...