C++: Pointer to Vectors....

Caporegime
Joined
18 Oct 2002
Posts
32,733
This is doing my head in...


SHORT VERSION:
I want to be able to save the address of a vector in another class.


LONG VERSION:
I am moddeling a swarm of robots in a simulator. I have 2 classes- Robot and Controller. In my simulator I have a vector of each (e.g. 20 robots with 20 seperate controllers). Within the Robot class there are some vectors that store some state information, such as the UIDs of the Neighbour robots, and also distances etc. Just think of these as vectors of ints and doubles etc. These vectors are updated every step of the simulation.

I want the Controller class to be able to point to the addresses of these Neighbour UIDs and distance vectors etc. i.e. within the Controller class I want a vector of ints that point to the address of the Robot vector. Thereby as the Robot vectors are updated the Controller vectors are automatically updated without me having to send and copy the vector each step.

PROBLEM:
The addresses do not seem to be saved properly.

CODE:
Code:
class Controller {

  std:: vector<int> * NeighbourUIDs_Vector;

  void setNeighbours(std::vector<int> *NeighbourUIDs){
      NeighbourUIDs_Vector = NeighbourUIDs
      // DEBUG TEST:
      printf("BB11 %i \n", &NeighbourUIDs);      // These are equal  BB11=BB22
      printf("BB22 %i \n", &NeighbourUIDs_Vector); 
  };

  void step(){
    printf("ADDRESS1 %i \n", &NeighbourUIDs_Vector);     // Wrong address
    printf("DEBUG %i \n", NeighbourUIDs_Vector.size());     // seg faults 
  }

};

Code:
class robot{
     std:: vector<int>  NeighbourUIDs_Vector;
    // some other stuff
};


// Main code
Code:
Robot robot;       // this is actually also a vector of e.g.20 robots
Controller controller;   // this is actually also a vector of e.g.20 robots


findNeighbours(){
   // find neighbour robots, blah blah. This code works fine
   robot.NeighbourUIDs_Vector.clear();  // clear vector
   robot.NeighbourUIDs_Vector = ..... // e.g. I update the vector
}

void Init(){

  robot = new Robot();    //this is basically repeated for all robots in the robot vector
  controller = new Controller();  // same here
 
  findNeighbours();    // Assign the neighbourUIDs to each robot

   // DEBUG
   printf("AA11 %i \n", &robot.NeighbourUIDs_Vector); 
  
  controller.setNeighbours(&robot.NeighbourUIDs_Vector);   // pass the address

   // DEBUG
   printf("AA22 %i \n", &controller.NeighbourUIDs_Vector); 

  controller.step(); // will now seg Fault.
}




During the Init function I find that:
AA11 = BB11 = BB22 but when the code returns to the init function the address has changed and the address has changed and AA22 does not equal AA11 etc..

Whjat am i doing worng. What is the best way to achieve what I want. I hope you understand my goal, nothing oo difficult. I just want a pointer to the Robot vector instead of having to allocate more memory and create a new vector in Controller each and every time step.
 
I think your problem lies in your printf() statements. The parameter to the setNeighbours() method is a pointer to a vector. The NeighbourUIDs_Vector in class Controller is also a pointer to a vector, hence the first assignment in setNeighbours() is correct... though missing a semicolon at the end...

However, when you print it out you are using the address-of operator on something that is already a pointer. In the first instance, you are getting the address of the pointer that is passed to the function. I'd expect that to be on the stack somewhere. In the second instance, you're getting the address of the pointer that's stored in your instance of the Controller class. I'm surprised you get these values equal. Try removing the & from the printf() statements.

In step(), you have the same problem with the &. Where you are getting a segmentation fault you're trying to access a method of a pointer, which is impossible. I'm surprised you don't get errors during compilation. You need to dereference the pointer first:

printf("DEBUG %i \n", NeighbourUIDs_Vector->size());
or
printf("DEBUG %i \n", (*NeighbourUIDs_Vector).size());

In Init(), you have the same problem with & but only for the AA22 output. The AA11 is fine because in that case you're getting the address of the actual object rather than a pointer to it. You're correctly passing the address to controller.setNeighbours() so the actual code should work. Just the debug statements that are wrong.

Note that I'm not sure what the %i will do. You'd be better off using %p to print a pointer. For example:

printf("BB11 %p \n", NeighbourUIDs);

Note that the %i should be fine in the last printf() in step() as you're actually getting an integer value back there rather than a pointer.

Hope that all made sense, and hope it helps sort out your problems.

[edit]One small caveat: it's been yonks since I did any C++ (I do C these days). The above *should* work equally with C and C++, but I concede that is a bit of an assumption...[/edit]
 
Think you have your pointers a little messed up.

For example - "&NeighbourUIDs", your getting the address of a pointer.

Try the below code, it should compile and work

Code:
#include <vector>
#include <stdio.h>
#include <iostream>

class Controller {
public:
  std:: vector<int> * NeighbourUIDs_Vector;

  void setNeighbours(std::vector<int> *NeighbourUIDs){
      NeighbourUIDs_Vector = NeighbourUIDs;
      // DEBUG TEST:
			std::cout << "BB11 :" << NeighbourUIDs << std::endl;      // These are equal  BB11=BB22
			std::cout << "BB22 : " << NeighbourUIDs_Vector << std::endl; 
  };

  void step(){
		std::cout << "ADDRESS1 " << NeighbourUIDs_Vector << std::endl;
		std::cout << "DEBUG " << NeighbourUIDs_Vector->size() << std::endl;
  }

};

class Robot{
public:
	std:: vector<int>  NeighbourUIDs_Vector;
};
    // some other stuff

Robot * robot;       // this is actually also a vector of e.g.20 robots
Controller * controller;   // this is actually also a vector of e.g.20 robots


void findNeighbours(){
   // find neighbour robots, blah blah. This code works fine
 //  robot.NeighbourUIDs_Vector.clear();  // clear vector
  // robot.NeighbourUIDs_Vector = ..... // e.g. I update the vector
}

void main(){

  robot = new Robot();    //this is basically repeated for all robots in the robot vector
  controller = new Controller();  // same here
 
  findNeighbours();    // Assign the neighbourUIDs to each robot

   // DEBUG
	std::cout << "AA11 " << &robot->NeighbourUIDs_Vector << std::endl;
  
  controller->setNeighbours(&robot->NeighbourUIDs_Vector);   // pass the address

   // DEBUG
	std::cout << "AA22 " << controller->NeighbourUIDs_Vector << std::endl;

  controller->step(); // will now seg Fault.
}
 
Ok, thanks for the help.
Yeah, my C++ is rusty after programming Java for the last 5 years!

i have it working in my test program, now to implement it in the real program.....
 
I have found my actual problem in the real program. One of these reasons I hate c++!!!!

Controller was actually a subclass of SwarmController. SwarmController had a double array of size 1. I was adding 4 elements to this array. Now this array is never touched, it is not read from or anything so shouldnt have really effected the code.

But it was overwriting the memory of the pointer, altering the address so it pointed to the wrong place.

In Java I would simply get an ArrayIndexOutOfBounds error and the program would still run. I would have saved my self 6 days of hand banging.

ARRRG!
 
Back
Top Bottom