带有谷歌时间戳的 Protobuf C++ 消息导致段错误 [重复]

Posted

技术标签:

【中文标题】带有谷歌时间戳的 Protobuf C++ 消息导致段错误 [重复]【英文标题】:Protobuf C++ message with google timestamp leads to seg fault [duplicate] 【发布时间】:2019-07-15 15:10:04 【问题描述】:

我是使用 google protobuffers 的新手,我创建了一条基本消息:

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

现在我创建了一个小型 c++ 程序来使用它[带有必要的标头]

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;

但是,这个程序给出了一个段错误。

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

我需要在哪里释放内存?

【问题讨论】:

Offtopic: timestamp.set_seconds(time(NULL)); 也是未定义的行为。没有崩溃的风险,只是你没有time返回秒数的保证。 timestamp.set_seconds(time(NULL));来自官方协议缓冲区网站developers.google.com/protocol-buffers/docs/reference/…,但显然我愿意接受更好的建议。 @MarekR 出于所有意图和目的,您确实有此保证。 【参考方案1】:

protobuf 的set_allocated_foo() 函数将取得指针的所有权,并在消息本身超出范围后尝试释放它。更多信息请访问https://developers.google.com/protocol-buffers/docs/reference/cpp-generated

由于您的指针指向自动对象,因此尝试删除此指针会产生未定义的行为,在您的情况下是核心转储。

要设置 protobuf 的时间戳,首先必须使用 mutable_timestamp 获取指向它的指针,然后可以设置它的各个字段。

【讨论】:

很遗憾,没有 set_timestamp。我使用了 set_allocated_timestamp 因为我找不到另一种令我惊讶的 set 方法。所以我的实际问题更多:如何在消息中设置时间戳 那么你必须new它而不是使用自动对象。 @Mike 我的错。时间戳本身就是一条消息。修正了答案。 ... 自动时间戳 = 新 google::protobuf::Timestamp;时间戳->set_seconds(time(NULL));时间戳->set_nanos(0); e.set_allocated_timestamp(时间戳); ...确实解决了问题。

以上是关于带有谷歌时间戳的 Protobuf C++ 消息导致段错误 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何解码二进制/原始谷歌 protobuf 数据

C++ - 谷歌 protobuf

将带有时间戳的向量整数连接为C++中的字符串?

带有日期和时间戳的 BBD 功能

用于非 protobuf 类的 protobuf `oneof` 功能的 C++ 实现

google protobuf 消息是不是具有带有元信息的可解析标头?