std::vector 覆盖最终值,而不是增长?
我遇到一个问题,使用 vector.push_back(value)
会覆盖最终值,而不是附加到末尾。为什么会发生这种情况?我在向量中有一个样本项,因此它的大小永远不会为零。下面是代码。
void UpdateTable(vector<MyStruct> *Individuals, MyStruct entry)
{
MyStruct someEntry;
bool isNewEntry = true;
for (int i = 0; i < Individuals->size(); i++)
{
if (!(strcmp(Individuals->at(i).sourceAddress, entry.sourceAddress)))
{
isNewEntry = false;
//snip. some work done here.
}
}
if(isNewEntry)
{
Individuals->push_back(entry);
}
}
这让我的第一个“样本”值保留下来,并且只允许向量中再添加一个项目。当添加 2 个新条目时,第二个条目会覆盖第一个条目,因此大小永远不会大于 2。
编辑:更多代码,因为这显然不是问题?
void *TableManagement(void *arg)
{
//NDP table to store discovered devices.
//Filled with a row of sample data.
vector<MyStruct> discoveryTable;
MyStruct sample;
sample.sourceAddress = "Sample";
sample.lastSeen = -1;
sample.beaconReceived = 1;
discoveryTable.push_back(sample);
srand(time(NULL));
while(1)
{
int sleepTime = rand() % 3;
sleep(sleepTime);
MyStruct newDiscovery = ReceivedValue();
if (newDiscovery.lastSeen != -1000) //no new value from receivedValue()
{
UpdateTable(&discoveryTable, newDiscovery);
}
printTable(&discoveryTable);
}
return NULL;
}
I'm having an issue where using vector.push_back(value)
is overwriting the final value, rather than appending to the end. Why might this happen? I have a sample item in the vector, so it's size never hits zero. Below is the code..
void UpdateTable(vector<MyStruct> *Individuals, MyStruct entry)
{
MyStruct someEntry;
bool isNewEntry = true;
for (int i = 0; i < Individuals->size(); i++)
{
if (!(strcmp(Individuals->at(i).sourceAddress, entry.sourceAddress)))
{
isNewEntry = false;
//snip. some work done here.
}
}
if(isNewEntry)
{
Individuals->push_back(entry);
}
}
This let's my first "sample" value stay in, and will allow for just one more item in the vector. When 2 new entries are added, the second overwrites the first, so the size is never larger than 2.
edit: More code, since this is apparently not the issue?
void *TableManagement(void *arg)
{
//NDP table to store discovered devices.
//Filled with a row of sample data.
vector<MyStruct> discoveryTable;
MyStruct sample;
sample.sourceAddress = "Sample";
sample.lastSeen = -1;
sample.beaconReceived = 1;
discoveryTable.push_back(sample);
srand(time(NULL));
while(1)
{
int sleepTime = rand() % 3;
sleep(sleepTime);
MyStruct newDiscovery = ReceivedValue();
if (newDiscovery.lastSeen != -1000) //no new value from receivedValue()
{
UpdateTable(&discoveryTable, newDiscovery);
}
printTable(&discoveryTable);
}
return NULL;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我将冒险猜测:
假设
MyStruct
声明为类似并且
ReceivedValue
执行类似的操作现在,您推入向量的每个结构都有
sourceAddress 指向同一个全局缓冲区,每次调用 ReceivedValue 时,它都会用新字符串覆盖该缓冲区 - 因此向量中的每个条目都以相同的字符串结束。
如果没有看到您的其余代码,我无法确定,但我可以确定,如果您遵循问题评论中的一些良好的 C++ 风格建议,这种可能性就会消失。
编辑澄清:不需要堆分配结构,只需将 sourceAddress 声明为 std::string 就足以消除这种可能性。
I'm going to hazard a guess:
Suppose
MyStruct
is declared likeAnd that
ReceivedValue
does something likeNow, every structure you push into your vector has
sourceAddress
pointing to the same global buffer, every time you callReceivedValue
it overwrites that buffer with the new string - so every entry in your vector ends up with the same string.I can't be sure without seeing the rest of your code, but I can be sure that if you follow some of the good C++ style suggestions in the comments to your question this possiblity would go away.
Edit for clarification: there's no need to heap allocate your structures, simply declaring sourceAddress as a std::string would be sufficient to eliminate this possibility.
您推入数据库的项目的范围即将到期。当您离开创建它们的
{}
时,它们就会被破坏 - 因此对它们的引用不再有效。您需要将其从
vector
更改为vector
(最好使用 Boost:: 中的安全指针而不是指针,但您明白了) 。您正在(有限)范围内创建项目并将其推送到向量上(当复制结构时,其中的字符串不是!)然后它会重用相同的内存位置(如果经过适当优化,最有可能)来存储下一个“新”结构以及之后的结构,依此类推。
相反,在有限的范围内创建
MyStruct *myObject = new MyStruct
并分配其值,然后将指针推送到向量。请记住在清除/销毁它之前
删除
向量中的所有值!或者,当然,您可以使用 std::string/CString/whatever 而不是 char数组并通过具有安全复制结构来完全避免该问题。
The scope for the items you are pushing into the database is expiring. They're being destructed when you leave the
{}
in which they were created - and as such the reference to them is no longer valid.You need to change it from
vector<MyStruct>
tovector<MyStruct*>
(preferably using safe pointers from Boost:: instead of pointers, but you get the idea).You are creating the item within the (limited) scope and pushing it onto the vector (while the struct is copied, the strings in it are not!) it then reuses the same memory location (most likely if properly optimized) to store the next "new" struct and the one after that and so on and so forth.
Instead, within the limited scope create
MyStruct *myObject = new MyStruct
and assign its values, then push the pointer to the vector.Remember to
delete
all values from the vector before clearing it/destroying it!!Or, of course, you could use std::string/CString/whatever instead of a char array and avoid the issue entirely by having a safe-to-copy struct.
ComputerGuru 的答案在另一种选择中有效。您可以为 MyStruct 创建复制构造函数并重载operator=。在这些操作中,您需要将实际字符串复制到新结构中。在 C++ 中,结构只不过是具有默认公共访问而不是默认私有访问的类。另一种替代方法是使用 std::string 而不是 char* 作为字符串值。 C++ 字符串已经具有这种行为。
ComputerGuru's answer works however there in another alternative. You can create a copy constructor and overload operator= for MyStruct. In these operations, you need to copy the actual string into the new struct. In C++, structs are nothing more than classes with default public access instead of default private access. Another alternative is to use std::string instead of char* for the string value. C++ strings already have this behavior.
我觉得很奇怪:也许代码的
//snip
部分有问题?尝试在
push_back
调用之前和之后记录向量的大小(在调试器中或使用cout
),并查看isNewEntry
代码>变量。Seems odd to me: Maybe there is something wrong with the
//snip
part of the code?Try to log the size of the vector before and after the
push_back
call (either in the debugger or usingcout
) and also have a look at theisNewEntry
variable.你的代码对我来说看起来没问题。您是否有可能没有传递正确的向量?我的意思是,如果在您尝试添加第三个条目之前您的个人向量以某种方式被重置为其原始的 1 条目状态,那么您所描述的行为就会出现,那么它看起来就像您的第二个条目被覆盖一样。
我的意思是:
如果这就是您的全部代码,那么问题就很明显了。但它可能隐藏在其他一些代码中。
Your code looks alright to me. Is it possible that you are not passing the right vector in? What I mean is that the behaviour you describe would appear if somehow your Individuals vector is being reset to its orginal 1-entry state before you tried to add the 3rd entry, then it would appear as if your 2nd entry was being overwritten.
Here is what I mean:
If this was all your code then the problem would be obvious. But it might be concealed in some other pieces of code.