对于指针类型的vector<DataType* >
,在使用push_back()
存入数据的操作时可能出现改变 vector 中前面存在的数据,在使用指针类型的 vector 时要注意这个问题。
列举一个例子来说明这个问题,使用的 vector 类型为 int*:
typedef std::vector<int*> ShitVector_pint;
下面的代码做的操作是向这个 examVector 这个 vector 中存入两个指向 int 类型的指针,并输出所指向的两个整数。
int _tmain(int argc, _TCHAR* argv[])
{
ShitVector_pint examVector;
int p_intnum_1 = 250;
int* p_int_1;
p_int_1 = &p_intnum_1;
examVector.push_back(p_int_1);
std::cout << *examVector[0] << std::endl;
int p_intnum_2 = 47;
// p_intnum_1 = 74; // p_intnum_1 的改变会引起 examVector 的实时变化
p_int_1 = &p_intnum_2;
examVector.push_back(p_int_1); // 一旦 p_intnum_1 重新赋值,examVector也更新了
std::cout << *examVector[0] << " " << *examVector[1] << std::endl;
system("pause");
return 0;
}
此时的输出结果是 *examVector[0] = 250; *examVector[1] = 47
:
但如果对 p_intnum_1 重新赋值,*examVector[0] 中的值也会随着一起改变。如果再加入一行代码p_intnum_1 = 74;
输出结果就成了*examVector[0] = 74; *examVector[1] = 47
:
之前的值 250 变成了新的值 74。
出现这个问题的原因在于vector<int*>
中存入的是 int 类型变量的地址,examVector[0] 中是 p_int_1 的地址, 当 p_int_1 变化时 examVector[0] 也会随着发生变化。这种情况的出现对简单的变量类型像 int 还好理解,对一些复杂的变量类型就不太容易找出什么原因,比如一个结构体类型:
void CBlockFun::AssignvOrhCoordint(CDC* pDC)
{
struct BlockDataStruct
{
double x, y, z; // 块的实际坐标
int DirctnD2U, // Down2Up, 0 || 1
DirctnU2D, // Up2Down, 0 || -1
DirctnR2L, // Right2Left, 0 || -1
DirctnL2R; // Left2Right, 0 || 1
CPoint Circord; // 圆圈坐标
CPoint Squcord; // 方块坐标
int CirNum, SquNum;
};
std::vector< BlockDataStruct* > vOrhCoordint;
BlockDataStruct* pBlockStrt = new BlockDataStruct;
pBlockStrt->DirctnD2U = 1;
pBlockStrt->DirctnU2D = 0;
pBlockStrt->DirctnL2R = 0;
pBlockStrt->DirctnR2L = 0;
pBlockStrt->Circord.x = InitialCordx;
pBlockStrt->Circord.y = InitialCordy;
pBlockStrt->Squcord.x = pBlockStrt->Circord.x +
LENGTHARROW * 2 * (pBlockStrt->DirctnL2R + pBlockStrt->DirctnR2L);
pBlockStrt->Squcord.y = pBlockStrt->Circord.y +
LENGTHARROW * 2 * (pBlockStrt->DirctnD2U + pBlockStrt->DirctnU2D);
pBlockStrt->CirNum = iInitlCirNum;
pBlockStrt->SquNum = iInitlSquNum;
vOrhCoordint.push_back(pBlockStrt);
/ *
// 向 vOrhCoordint 中再继续放入元素
// !!! pBlockStrt 改变后,vOrhCoordint 也跟着变了
pBlockStrt->Circord.x = vOrhCoordint[i-1]->Squcord.x +
(pBlockStrt->DirctnL2R + pBlockStrt->DirctnR2L) * LENGTHARROW * 2;
pBlockStrt->Circord.y = vOrhCoordint[i-1]->Squcord.y +
(pBlockStrt->DirctnD2U + pBlockStrt->DirctnU2D) * LENGTHARROW * 2;
pBlockStrt->Squcord.x = pBlockStrt->Circord.x +
LENGTHARROW * 2 * (pBlockStrt->DirctnL2R + pBlockStrt->DirctnR2L);
pBlockStrt->Squcord.y = pBlockStrt->Circord.y +
LENGTHARROW * 2 * (pBlockStrt->DirctnD2U + pBlockStrt->DirctnU2D);
pBlockStrt->CirNum = vOrhCoordint[i-1]->CirNum + 1;
pBlockStrt->SquNum = vOrhCoordint[i-1]->SquNum + 1;
vOrhCoordint.push_back(pBlockStrt);
// 删除 pBlockStrt 后 vOrhCoordint 中的值也没了
delete pBlockStrt;* /
}
pBlockStrt 是指向结构体类型的指针,向 vOrhCoordint 中添加值的时候通过 pBlockStrt 来完成的,在第一次操作vOrhCoordint.push_back(pBlockStrt)
后,对 pBlockStrt 重新赋值就会使得 vOrthCoordint 存入的内容也跟着改变,这个错误问题在复杂些的情况不太容易发现。
问题的总结:
1. 对指针类型的 vector 添加元素的操作注意 push_back() 中的指针内容变化,值的传递会影响 vector 中的内容。
2. 指针的值传递没有理解的太好,还是要多注意下指针的操作。
3. 对 vector 的使用要稍微熟悉些了,这问题解决虽然花了一整天,但还开始会调试了,算是有收获。
4. 2、3条是废话。