当需要用vector以及map等容器存储一些类的对象时,如果这个类里数据成员有一些new出来的指针,那么当你压入这个对象时有可能里面的指针就被析构掉了。
如果你压入的是这个对象的指针,但是由于这个指针指向的是这个对象的地址,如果这个对象发生了变化,原先压入的对象也会发生相应的变化。
以下是一些错误的做法
voronoicell c;
map<int, voronoicell*> cells_1;
map<int, voronoicell> cells_2;
while (1){
compute_cell(c);
*cell_temp = c;
cells_1.insert(make_pair(cell_id,cell_temp));
cells_2.insert(make_pair(cell_id,c));
}
voronoicell是一个类,里面有的数据成员是new出来的,即动态分配内存的。
以上第一个做法是压入c的指针,但是进入下一个循环的时候,如果c的数据成员发生改变,cells_1中先前压入的c的指针也会发生相应的变化。所以无效!
第二个做法是压入c本身,但是map等STL容器在压入新的对象的时候,如果原先的空间不够的话,map会new出一个新的空间,把原来的数据成员拷贝出来,放到那个新的空间里,再把原来的空间析构掉。但是原来的空间保存了原先数据成员(那个new出来的指针)的地址,如果被析构掉的话,新空间里面的数据成员将指向一个无效的地址。那么c里面的那些动态分配的数据成员将全部无效。
正确的做法是new出来一个空间,来存储一个临时的变量,将c赋值到这个空间的临时变量里(这个new出来的空间如果你自己不手动析构,程序将不会将其析构掉)。再将这个new出来的空间里的变量压入到容器里面。
以下是正确的做法:
voronoicell *cell_temp = new voro::voronoicell[1];
*cell_temp = c;
cells_1.insert(make_pair(cell_id,cell_temp));