0

Given a message

message My_msg{
  repeated double my_arr = 1;
}

How can one append elements into the field?

There is an answer for copying/moving already allocated full arrays by overwriting the current contents, but what if there is already some data in the filed, which needs to be kept as it is?

Is using the below code to do it safe?

void set_data(std::vector<double> table, My_msg* message){ /* suppose message is valid */
  message->mutable_my_arr()->Resize(message->my_arr_size() + table.size(),0);
  message->mutable_my_arr()[message->my_arr_size() - table.size()] = {table.begin(),table.end()};
}
Dávid Tóth
  • 2,788
  • 1
  • 21
  • 46

2 Answers2

1

I don't think your sample code would build. My_msg::mutable_my_arr() returns a pointer to a RepeatedField (not the first element of an array). Trying to index it would segfault at best.

In terms or performance, if you have your data in an std::vector you will always need to copy - so you could just try to make that faster.

You can call RepeatedField::Reserve before. Then you can either write a loop, or use RepeatedFieldBackInserter:

void set_data(const std::vector<double>& table, My_msg* message){
  message->mutable_my_arr()->Reserve(message->my_arr_size() + table.size());
  std::copy(
      table.begin(),
      table.end(), 
      RepeatedFieldBackInserter(message->mutable_my_arr()));
}
Rafael Lerm
  • 1,340
  • 7
  • 10
  • But it does compile. [It's list initialization](https://stackoverflow.com/a/49822561/1467600) combined with the copy equality operator. The assumption of segfault might be true however. Thank you for the tip, std::copy seems to be the way here. – Dávid Tóth Jul 26 '20 at 11:27
  • I think you're right that it builds, but it would try to access the `RepeatedField` as the first element of an array, which would probably segfault. That said, the only real point of this answer is to use `Reserve`, everything else is details. – Rafael Lerm Jul 27 '20 at 14:57
  • Can confirm, compilation success but segfault upon usage. Thank you for the answer! – Dávid Tóth Jul 28 '20 at 05:24
0

Just call My_msg::add_my_arr:

void set_data(std::vector<double> table, My_msg* message) {
    for (auto ele : table) {
        message->add_my_arr(ele);
    }
}
for_stack
  • 21,012
  • 4
  • 35
  • 48