简体   繁体   English

std :: vector覆盖最终值,而不是增长?

[英]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.

相关问题 如果 KEY 是 std::list 或 std::vector 而不是值,则 std::map 的默认行为是什么? - What is the default behavior of a std::map if, rather than the value, the KEY is a std::list or std::vector? 为什么std :: when_any使用std :: tuple而不是std :: vector作为结果类型? - Why does std::when_any use std::tuple rather than std::vector as its result type? 为什么我应该将 std::span 而不是 std::vector&amp; 传递给 function? - Why in particular should I rather pass a std::span than a std::vector& to a function? C ++ std :: vector在类中,函数崩溃,返回值和大小在foreach中增长 - C++ std::vector in class, function crash on returning value and size growing in foreach 为什么 std::vector 需要 is_trivial 进行按位移动,而不仅仅是 is_trivially_copyable? - Why does std::vector require is_trivial for bitwise move, rather than just is_trivially_copyable? 为什么std :: map :: insert不能使用键和值而不是std :: pair? - Why can't std::map::insert take a key and a value rather than an std::pair? 使用 std::transform 最终向量保持为空 - using std::transform the final vector remains empty C++ 增长 std::vector 的可移动引用计数指针 - C++ growing std::vector of movable reference counting pointer 按值返回std :: vector - Returning std::vector by value std :: vector中的值传播 - value propagation in a std::vector
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM