【发布时间】:2020-10-25 21:49:42
【问题描述】:
我正在使用 protobuf 3 序列化一个简单的消息。
当我像这样为我的 protobuf 消息的成员之一设置字符串值时,我得到了一个错误的分配。
std::string a("eeee");
hello_in.set_name(a);
bad alloc 异常发生在此函数的 libprotobuf.dll 中...
void CreateInstance(Arena* arena, const ::std::string* initial_value) {
GOOGLE_DCHECK(initial_value != NULL);
// uses "new ::std::string" when arena is nullptr
ptr_ = Arena::Create< ::std::string>(arena, *initial_value);
}
但我认为真正的问题是initial_value 已经以某种方式损坏并且大小为[size] = 3435973836。
不确定这是如何损坏的。 CreateInstance 在此之前确实被调用了几次,但它是第一次从 main.cpp 调用。这让我相信它与 dll 和内存所有权有关。
使用任何其他 set_name 函数也会导致错误的分配异常。 在消息中设置 bool 或 int 可以正常工作。
这是消息和 main.cpp。我没有包括 hello.pb.h/pb.cc,因为它们很大,但如果有帮助可以。
// See README.txt for information and build instructions.
//
// Note: START and END tags are used in comments to define sections used in
// tutorials. They are not part of the syntax for Protocol Buffers.
//
// To get an in-depth walkthrough of this file and the related examples, see:
// https://developers.google.com/protocol-buffers/docs/tutorials
// [START declaration]
syntax = "proto3";
package commands;
import "google/protobuf/timestamp.proto";
// [END declaration]
// [START messages]
message Hello {
string name = 1;
int32 id = 2; // Unique ID number for this person.
bool on = 3;
google.protobuf.Timestamp last_updated = 4;
}
// [END messages]
#include "hello.pb.h"
// stl
#include <fstream>
#include <iostream>
int main()
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
commands::Hello hello_in;
hello_in.set_id(2);
std::string a("eeee");
hello_in.set_name(a);
hello_in.set_on(false);
{
// Write the new address book back to disk.
std::fstream output("hello.txt", std::ios::out | std::ios::trunc | std::ios::binary);
if (!hello_in.SerializeToOstream(&output)) {
std::cerr << "Failed to write address book." << std::endl;
return -1;
}
}
commands::Hello hello_out;
{
// Read the existing address book.
std::fstream input("hello.txt", std::ios::in | std::ios::binary);
if (!input) {
std::cout << "hello.txt" << ": File not found. Creating a new file." << std::endl;
}
else if (!hello_out.ParseFromIstream(&input)) {
std::cerr << "Failed to parse address book." << std::endl;
return -1;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
【问题讨论】:
-
仅供参考:它在 Ubuntu 18.04 上运行良好。你试过
hello_in.set_name("eeee");吗? -
@Azeem 是的。它不能解决问题。
-
考虑在其 GitHub 存储库上为此创建一个问题。首先检查现有问题是否相似。
标签: protocol-buffers protobuf-c