[英]std::vector overwriting final value, rather than growing?
I'm having an issue where using vector.push_back(value)
is overwriting the final value, rather than appending to the end. 我遇到一个问题,其中使用
vector.push_back(value)
会覆盖最终值,而不是附加到末尾。 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.
添加2个新条目时,第二个覆盖第一个,因此大小永远不会大于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;
}
I'm going to hazard a guess: 我要冒险猜测:
Suppose MyStruct
is declared like 假设
MyStruct
声明为
struct MyStruct
{
const char *sourceAddress;
// Other Gubbins ...
};
And that ReceivedValue
does something like 并且
ReceivedValue
执行类似
MyStruct ReceivedValue()
{
static char nameBuffer[MAX_NAME_LEN];
// Do some work to get the value, put the name in the buffer
MyStruct s;
s.sourceAddress = nameBuffer;
// Fill out the rest of MyStruct
return s;
}
Now, every structure you push into your vector has sourceAddress
pointing to the same global buffer, every time you call ReceivedValue
it overwrites that buffer with the new string - so every entry in your vector ends up with the same string. 现在,您推入向量的每个结构都具有指向同一全局缓冲区的
sourceAddress
,每次调用ReceivedValue
它将用新字符串覆盖该缓冲区-因此向量中的每个条目都以相同的字符串结尾。
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. 我无法确定是否看不到其余的代码,但是可以确定的是,如果您遵循对问题的评论中的一些C ++风格的良好建议,这种可能性就会消失。
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. 编辑以进行澄清:无需堆分配您的结构,只需将sourceAddress声明为std :: string就足以消除这种可能性。
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>
to vector<MyStruct*>
(preferably using safe pointers from Boost:: instead of pointers, but you get the idea). 您需要将其从
vector<MyStruct>
更改为vector<MyStruct*>
(最好使用Boost ::的安全指针,而不是指针,但您会明白)。
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. 而是在有限范围内创建
MyStruct *myObject = new MyStruct
并分配其值,然后将指针推到向量。
Remember to delete
all values from the vector before clearing it/destroying it!! 在清除/销毁向量之前,请记住从向量中
delete
所有值!
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. 或者,当然,您可以使用std :: string / CString / whatever而不是char数组,并通过具有可复制的结构完全避免此问题。
ComputerGuru's answer works however there in another alternative. 但是ComputerGuru的答案可以在另一种方法中起作用。 You can create a copy constructor and overload operator= for MyStruct.
您可以为MyStruct创建副本构造函数和重载operator =。 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.
在C ++中,结构只不过是具有默认公共访问权限而不是默认私有访问权限的类。 Another alternative is to use std::string instead of char* for the string value.
另一种选择是使用std :: string代替char *作为字符串值。 C++ strings already have this behavior.
C ++字符串已经具有此行为。
struct MyStruct {
std::string sourceAddress;
int lastSeen;
int beaconReceived;
};
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.
我的意思是,如果您试图在添加第三个条目之前以某种方式将“个人”向量重置为原始的1个条目状态,则将出现您所描述的行为,然后好像您的第二个条目已被覆盖。
Here is what I mean: 这是我的意思:
int test_table()
{
string SampleAddresses[] = {"Sample Address 1", "Sample Address 2"};
for (int i = 0; i < 2; i++)
{
// All this work to build the table *should* be done outside the loop; but we've accidentally put it inside
// So the 2nd time around we will destroy all the work we did the 1st time
vector<MyStruct> Individuals;
MyStruct Sample;
Sample.sourceAddress = "Sample Address 0";
Test.push_back(Sample);
// this is all we meant to have in the loop
MyStruct NewEntry;
NewEntry.sourceAddress = SampleAddresses[i];
UpdateTable(Individuals, NewEntry);
}
//Now the table has 2 entries - Sample Address 0 and Sample Address 2.
}
If this was all your code then the problem would be obvious. 如果这是您所有的代码,那么问题将很明显。 But it might be concealed in some other pieces of code.
但是它可能被其他一些代码隐藏了。
Seems odd to me: Maybe there is something wrong with the //snip
part of the code? 对我来说似乎很奇怪:代码的
//snip
部分可能有问题吗?
Try to log the size of the vector before and after the push_back
call (either in the debugger or using cout
) and also have a look at the isNewEntry
variable. 尝试在
push_back
调用之前和之后记录矢量的大小(在调试器中或使用cout
),并查看isNewEntry
变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.