对象和指针的C++向量

Zek*_*eke 2 c++ pointers vector

这是一个人为的例子,说明了我遇到的问题.基本上,我创建了一个对象向量,然后是一个指向对象的指针向量,然后打印指针和解除引用的对象.

#include <vector>
#include <iostream>

using namespace std;

namespace {
    struct MyClass {
        int* MyInt;
        MyClass(int* i) : MyInt(i) {}
    };

    struct MyBigClass {
        vector<MyClass> AllMyClassRecords;  // Where I keep the MyClass instances
        vector<int> TheInts;

        void loadMyClasses();
        void readMyClasses();
        MyBigClass() {}
    };

}

void MyBigClass::loadMyClasses() {
    for (int i = 0; i < 10; ++i) {
        TheInts.push_back(i);   // Create an int
        int *j = &TheInts[TheInts.size() - 1];  // Create a pointer to the new int
        AllMyClassRecords.push_back(MyClass(j));    // Create a MyClass using pointer
    }
}

void MyBigClass::readMyClasses() {
    for (vector<MyClass>::iterator it = AllMyClassRecords.begin();
            it != AllMyClassRecords.end(); ++it)
        cout << it->MyInt << " => " << *(it->MyInt) << endl;
}

int main() {
    MyBigClass MBC;

    MBC.loadMyClasses();
    MBC.readMyClasses();
}
Run Code Online (Sandbox Code Playgroud)

基本上,我想创建一个指向另一个int向量的指针向量.问题是此代码打印出以下内容:

0x97ea008 => 159293472
0x97ea02c => 1
0x97ea040 => 2
0x97ea044 => 3
0x97ea078 => 4
0x97ea07c => 5
0x97ea080 => 6
0x97ea084 => 7
0x97ea0d8 => 8
0x97ea0dc => 9
Run Code Online (Sandbox Code Playgroud)

它似乎按预期工作,除了第一个值,这可能是内存中的一些垃圾.为什么只有第一个值受到影响?如果我的代码被破坏了,为什么它只被插入第一个指针?


更新:我正在使用g++Ubuntu 编译它.至于我正在做什么,我正在创建一个编译器分析通道.该MyClass对象保存有关指令,我想,当我找到特定的寄存器更新信息.寄存器号索引矢量矢量,因此特定的寄存器号将具有矢量MyClass*s.因此,如果找到寄存器MyClass,则向量中的任何指针将用于更新MyClass保持在单独MyClass向量中的对象.因为我正在累积存储在MyClass对象中的指令信息和必须跟随MyClass指针的寄存器信息,所以我无法创建整个MyClass向量而不创建单独的传递,我想避免.


Update2:现在有了图片......

Pass Progress           inserts...   InstRecs (TheInt)  and updates...  UpdatePtrs (MyClass) 
----------------------              ------------------                  -----------------------
| => I1: Uses r0, r1 |              | InstRec for I1 |                  | r0: InstRec for I1* |
|    I2: Uses r0, r2 |              ------------------                  | r1: InstRec for I1* |
----------------------                                                  -----------------------
Run Code Online (Sandbox Code Playgroud)

首先,pass传入一个InstRec,其中包含有关I1的信息.它还会创建指向由寄存器编号索引的新InstRec的指针.这里的r0实际上是指向IRe的InstRec的一个元素的向量,因此如果在后续指令中再次遇到r0,则将更新用于I1的InstRec.

Pass Progress           inserts...   InstRecs (TheInt)  and updates...  UpdatePtrs (MyClass) 
----------------------              ------------------                  -----------------------
|    I1: Uses r0, r1 |              | InstRec for I1 |                  | r0: InstRec for I1* |
| => I2: Uses r0, r2 |              | InstRec for I2 |                  |     InstRec for I2* |
----------------------              ------------------                  | r1: InstRec for I1* |
                                                                        | r2: InstRec for I2* |
                                                                        -----------------------
Run Code Online (Sandbox Code Playgroud)

同样,第二个条目将插入到InstRecs中,指针将添加到UpdatePtrs结构中.由于I2使用r0,因此另一个InstRec指针被推送到r0向量.未示出:当检测到I2使用r0时,传递在指针的r0向量的UpdatePtrs结构中查找,跟随每个指向其InstRec条目的指针,并用新信息更新InstRec.

希望这使我想要做的更清楚一些.我已经实现了@MerickOWA首先提出的使用InstRec向量索引而不是InstRec指针的建议(因为一旦将InstRecs添加到数组中,它们就永远不会移动),它现在似乎正在工作.

Joh*_*ing 6

你在做什么非常类似于创建这样的东西:

vector<int> MyInts;
vector< vector<int>::iterator > MyIntIters;
Run Code Online (Sandbox Code Playgroud)

然后每次添加一个新的int时MyInts,都会得到迭代器并将迭代器推入MyIntIters.

你不能用a来做这个,vector因为只要你添加一个新的int,迭代器就会变得无效MyInts.

所以你的整个结构都被打破了.你需要提出一个全新的设计.首先,我问你为什么要一个迭代器(或指针)向量到另一个向量.是排序吗?索引以某种方式?别的什么?无论你想做什么,肯定有更好的方法. 什么你试图做将有助于确定如何做到这一点.

编辑:

在多次阅读和重新阅读您的更新后,在我看来,您正在尝试创建一个glom矢量.也就是说,一个可变长度的缓冲区,它在开头有结构化数据,后面有其他东西.

这是相当棘手的业务,它需要动态分配.但是,您没有使用动态分配 - 您可以按值将对象推送到向量中.指向这些对象的指针将随着向量的调整大小和洗牌而改变.

因此,如果这是你正在尝试做的事情,你需要改变一些东西,以便你使用创建你的glom new,并将指针推到向量上的glom.这打开了整个潘多拉盒子的麻烦.你有多大的缓冲区?你怎么解决这个问题?你如何处理深拷贝,调整大小等?如何在不泄漏筛子的情况下正确释放胶体?正如我所说,棘手的业务.在我的工作中,我们一直在做这类事情,并且我们使用了一系列标准做法.这些需要花费很多精力和大量的测试和试验才能做到正确,我们仍然会发现问题.如果这就是你正在做的事情,你可能会考虑采取另一种方式.