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

对于指针类型的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);

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

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

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

猜你喜欢

转载自blog.csdn.net/Mr_Grit/article/details/46346517