【问题标题】:Protobuf exception when allocating memory for string in dll为 dll 中的字符串分配内存时出现 Protobuf 异常
【发布时间】: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


【解决方案1】:

我观察到了相同的行为(Visual Studio 2019 C++ 项目)。对我有帮助的解决方案:libprotobuf.lib 和 libprotobuf.dll 在 debug/x86 模式下被其调试版本 libprotobufd.lib 和 libprotobufd.dll 替换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    相关资源
    最近更新 更多