您的位置:首页 > 其它

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

2015-06-03 16:43 316 查看
对于指针类型的
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条是废话。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息