vector.push_back corrupts referenced object???

Hi all! New here in the forums, hope someone might be able to help with this.
Im working on a small GP project, and in particular on the crossover functions, where parental GP function pointers (part of an instruction set stored in a vector) are copied to the offspring programs.
The program class is as simple and stupid as possible. When im trying to crossover two parents and create offspring, i do so in a for loop. Parent programs are passed in the function by reference and not copied. When i do not pass the parents by reference but as objects being copied, the code i have below works fine. When however i pass them by reference, the first loop works fine, until the part where the offspring program is pushed back in the population. At this point, the "by reference" parent addresses get "screwed up" and while going in the second loop, program crashes giving me a "vector subscript out of range" which is normal, since the details in the object "father" are not legit anymore.
Does this happen because when the new program get's pushed back, the vector changes address ? I've traced/stepped into the code many times, and this is the only idea i could come up with... heres the actual code, if more info is required, or if there is a way to do something about the vector beforehand so that this does not happen, please let me know...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void crossover(const Program &father,const Program &mother, int offspring, std::vector<Program>& population, bool StdVar){
	std::vector<ptr2func> temp_sequence;									
	sequence f_seq;																				
	sequence m_seq;																				

	for (int i=0; i < offspring; i++){															
		if (getSequencePos(father,StdVar,true,f_seq)){									
			if(getSequencePos(mother,StdVar,false,m_seq)){							
				for (unsigned int s1 = f_seq.s_pos; s1 < f_seq.e_pos; s1++){		
					temp_sequence.push_back(father.instructions[s1]);				
				}
				for (unsigned int s2 = m_seq.s_pos; s2 < m_seq.e_pos; s2++){	
					temp_sequence.push_back(mother.instructions[s2]);				
				}
				Program program;																	
				program.executions=0;													
				program.fitness=0;														
				program.ID = population.size()+1;											
				std::cout << "Offspring's ID: "<< program.ID <<std::endl;
				program.father = father.ID;												
				program.mother = mother.ID;											
				program.size = temp_sequence.size();										
				program.step_exec = 0;															
				for (unsigned int k = 0; k < temp_sequence.size(); k++){		
					program.instructions.push_back(temp_sequence[k]);			
					
				}
				std::cout << "Offspring's Size: "<< program.size << std::endl;
				population.push_back(program);
			}
		}
	}
}


Right at the last instruction population.push_back(program); is when the address and details of
father
and
mother
get all messed up. Im assuming that the vector re-arranges the population when the new program gets pushed back, and thus references to father and mother get also messed up. This does NOT happen when i pass father and mother as copies of objects. Can anyone please help ?

PS: Sorry if the page got too wide, this happened when i copy-pasted the code...
What is the type of ptr2func and what are the types of the father/mother.instructions?
Nevermind, that was it, once pushed back, everything shifts and screwed up. I reserved the population vector prior to calling this function and everything worked fine. i wonder if i copied the addresses of father & mother if they would still be the same after pushing back a new program...

ptr2func is a typedef'd pointer to a function, and so are the father mother instructions (vectors containing ptr2func).

I should had read the vector manual more carefull. Would it cost me too much in memory/performance if i increased the vector capacity beforehand? I know for a fact that it will be increasing by alot... Or should i keep it minimal and only increase it if required?
Last edited on
That depends n what you are doing. Naturally, try to save space. But if you are going to be adding a lot of items to the vector, reserving can save time as it will only to one reserve as opposed to multiple as you add individual elements.
Now i'm even more puzzled...
So i reserved prior to calling the function (reserving within the function just screwed up the father/mother reference right away).

And then i go in a for loop doing the reserve and then crossover function many times.
So i would have expected to see that after the reserve & push back the original addresses in the vector would have changed. But they have not!!!

So, did reserve actually increase the end of the vector, and thus effectively did not "touch" the first objects & their addresses ?

Im very concerned about this, because each offspring keeps a pointer to it's father & mother, but if as i'm adding offspring and deleting parents, elements get shifted around in the vector, doesn't that mean, that their addresses will at some point change? And thus the offspring's pointer will be pointing at something irrelevant (or worse to the wrong father/mother?)

Maybe the population vector should hold pointers to objects after all, and not the actual objects...
Reserve increases the size of the vector's internal memory, which may or may not have to copy it.

A vector guarantees that &v[0]+x == &v[x]. They vector may however, be copied around, so doing things like: some_ptr = &v[0]; is not the best idea.
Last edited on
Topic archived. No new replies allowed.