Сообщение Protobuf C++ с отметкой времени Google приводит к ошибке seg

Я новичок в использовании протобуферов Google, и я создал базовое сообщение:

message msg {  
    uint32 id = 1;                             
    google.protobuf.Timestamp timestamp = 2;  
}

Теперь я создал небольшую программу на С++, чтобы использовать это [с необходимыми заголовками]

int main(void) {
  auto m = msg{};
  m.set_id(2);
  auto timestamp = google::protobuf::Timestamp{};
  timestamp.set_seconds(time(NULL));
  timestamp.set_nanos(0);

  m.set_allocated_timestamp(&timestamp);

  std::cout << m.id() << std::endl;
  std::cout << m.timestamp().seconds() << std::endl;

  return 0;
}

Однако эта программа выдает ошибку seg.

free(): invalid pointer
[1]    9537 abort (core dumped) 

где мне нужно освободить память?


person Mike    schedule 15.07.2019    source источник
comment
Оффтопик: timestamp.set_seconds(time(NULL)); тоже неопределённое поведение. Нет риска сбоя, просто у вас нет гарантии, что time вернет секунды.   -  person Marek R    schedule 15.07.2019
comment
timestamp.set_seconds (время (NULL)); взято с официального сайта буфера протокола developers.google .com/protocol-buffers/docs/reference/, но, очевидно, я открыт для лучших предложений.   -  person Mike    schedule 15.07.2019
comment
@MarekR во всех смыслах, у вас есть эта гарантия.   -  person SergeyA    schedule 15.07.2019


Ответы (1)


Функция protobuf set_allocated_foo() получит владение указателем и попытается освободить его после того, как само сообщение выйдет за пределы области видимости. Подробнее см. на странице https://developers.google.com/protocol-buffers/docs/reference/cpp-generated

Поскольку ваш указатель указывает на автоматический объект, попытка удаления этого указателя приводит к неопределенному поведению, в вашем случае к дампу ядра.

Чтобы установить временную метку protobuf, вам сначала нужно получить указатель на нее с помощью mutable_timestamp, а затем вы можете установить ее отдельные поля.

person SergeyA    schedule 15.07.2019
comment
К сожалению, нет set_timestamp. Я использовал set_allocated_timestamp, так как, к моему удивлению, не смог найти другого метода set. Итак, мой фактический вопрос здесь больше: как установить временную метку в сообщении - person Mike; 15.07.2019
comment
Затем вам нужно new вместо использования автоматического объекта. - person Goswin von Brederlow; 15.07.2019
comment
@Майк мой плохой. Временная метка — это отдельное сообщение. Исправил ответ. - person SergeyA; 15.07.2019
comment
... auto timestamp = new google::protobuf::Timestamp{}; метка времени-›set_seconds(time(NULL)); отметка времени-›set_nanos(0); e.set_allocated_timestamp (отметка времени); ... действительно устраняет проблему. - person Mike; 15.07.2019