【发布时间】:2010-12-01 03:54:15
【问题描述】:
这是一个人为的例子,说明了我遇到的一个问题。基本上,我创建一个对象向量,然后创建一个指向对象的指针向量,然后打印指针和取消引用的对象。
#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();
}
基本上,我想创建一个指向另一个整数向量的指针向量。问题是这段代码打印出以下内容:
0x97ea008 => 159293472
0x97ea02c => 1
0x97ea040 => 2
0x97ea044 => 3
0x97ea078 => 4
0x97ea07c => 5
0x97ea080 => 6
0x97ea084 => 7
0x97ea0d8 => 8
0x97ea0dc => 9
除了第一个值外,它似乎按预期工作,这可能是内存中的一些垃圾。为什么只有第一个值受到影响?如果我的代码坏了,为什么只插入第一个指针就坏了?
更新:我在 Ubuntu 上使用 g++ 编译它。至于我正在做什么,我正在创建一个编译器分析通道。 MyClass 对象包含有关指令的信息,当我找到某些寄存器时,我想更新这些信息。寄存器编号索引向量向量,因此特定寄存器编号将具有MyClass*s 的向量。因此,如果找到寄存器,则向量中的任何MyClass 指针都将用于更新单独的MyClass 向量中保存的MyClass 对象。因为我正在累积存储在MyClass 对象中的指令信息和必须遵循MyClass 指针的寄存器信息,所以我不能先创建整个MyClass 向量而不创建单独的传递,我想避免.
更新2:现在有图片...
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* |
---------------------- -----------------------
首先,pass 插入一个 InstRec,其中包含有关 I1 的信息。它还创建指向这个由寄存器编号索引的新 InstRec 的指针。这里的 r0 实际上是一个元素的向量,它指向 I1 的 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* |
-----------------------
同样,第二个条目将被插入到 InstRecs 中,并且指针将被添加到 UpdatePtrs 结构中。由于 I2 使用 r0,另一个 InstRec 指针被推到 r0 向量。未显示的是:当检测到 I2 使用 r0 时,pass 在 UpdatePtrs 结构中查找 r0 指针向量,跟随每个指向其 InstRec 条目的指针,并使用新信息更新 InstRec。
希望这能让我想要做的事情更加清晰。我已经实现了@MerickOWA 首次提出的使用 InstRec 向量索引而不是 InstRec 指针的建议(因为一旦将 InstRec 添加到数组中,它们就永远不会移动),它现在似乎正在工作。
【问题讨论】:
-
如果你在 Release 中编译和运行,我想你会发现它不仅仅是第一个坏的,而是所有的。
-
我完全糊涂了。这无疑部分是由于我对您的问题领域不熟悉。你能用更笼统的说法重新表述一下,以便像我这样的傻瓜能理解吗?
-
查看我的编辑。它可能在正确的道路上,也可能不在正确的道路上。
-
你真的需要像访问 MyClass 这样的随机访问数组吗?如果您仅使用指针向量来访问 MyClass,那么向量的额外功能并不是真正有用,并且只会在向量移动所有内容时引起问题。也许试试 std::list 代替 MyClass?
-
@John:我用一些图表再次更新了这个问题。我在我的代码中解决了这个问题,但我在问题中添加了更多信息,以防你仍然感兴趣。