向指针类型的vector中添加元素的问题

时间:2022-07-29 04:19:16

对于指针类型的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
向指针类型的vector中添加元素的问题
但如果对 p_intnum_1 重新赋值,*examVector[0] 中的值也会随着一起改变。如果再加入一行代码p_intnum_1 = 74; 输出结果就成了*examVector[0] = 74; *examVector[1] = 47
向指针类型的vector中添加元素的问题
之前的值 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);

// 删除 pBlockStrtvOrhCoordint 中的值也没了
delete pBlockStrt;* /
}

pBlockStrt 是指向结构体类型的指针,向 vOrhCoordint 中添加值的时候通过 pBlockStrt 来完成的,在第一次操作vOrhCoordint.push_back(pBlockStrt) 后,对 pBlockStrt 重新赋值就会使得 vOrthCoordint 存入的内容也跟着改变,这个错误问题在复杂些的情况不太容易发现。

问题的总结:
1. 对指针类型的 vector 添加元素的操作注意 push_back() 中的指针内容变化,值的传递会影响 vector 中的内容。
2. 指针的值传递没有理解的太好,还是要多注意下指针的操作。
3. 对 vector 的使用要稍微熟悉些了,这问题解决虽然花了一整天,但还开始会调试了,算是有收获。
4. 2、3条是废话。