我正在尝试在简单的C 程序中使用协议缓冲区。当我使用g++
编译时,程序正常执行并退出。当我使用clang++
编译时,程序失败了,抱怨pointer being freed was not allocated
。
协议缓冲区消息定义
package test;
message Test {
required int32 id = 1;
required string name = 2;
}
主类
#include <iostream>
#include "test.pb.h"
int main(void) {
// Build the original message
test::Test original;
original.set_id(0);
original.set_name("original");
// Serialize the original message
int size = original.ByteSize();
char data[size];
original.SerializeToArray(data, size);
// Deserialize the data into a previously initialized message
test::Test success;
success.set_id(1);
success.set_name("success");
success.ParseFromArray(data, size);
std::cout << success.id() << ": " << success.name() << std::endl;
// Deserialize the data into an uninitialized message
test::Test failure;
failure.ParseFromArray(data, size); // FAILS HERE WITH CLANG++
std::cout << failure.id() << ": " << failure.name() << std::endl;
}
g 输出
theisenp$ g++ test.pb.cc main.cpp -lprotobuf -o g++.out
theisenp$ ./g++.out
0: original
0: original
clang 输出
theisenp$ clang++ test.pb.cc main.cpp -L/usr/local/lib -lprotobuf -stdlib=libstdc++ -o clang++.out
theisenp$ ./clang++.out
0: original
clang++.out(9948,0x7fff71195310) malloc: *** error for object 0x7fff72ed6330: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
我是协议缓冲区和clang的新手,因此我很可能缺少明显的东西。有什么想法吗?
编辑
关于编译器版本的一些澄清。我正在运行OSX Mavericks(10.9.1)。默认情况下,Mavericks地图分别呼叫gcc
和g++
分别为clang
和clang++
。我已经独立安装了gcc
4.8.2并覆盖了默认行为。
G 版本
theisenp$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc48/4.8.2/libexec/gcc/x86_64-apple-darwin13.0.2/4.8.2/lto-wrapper
Target: x86_64-apple-darwin13.0.2
Configured with: ../configure
--build=x86_64-apple-darwin13.0.2
--prefix=/usr/local/Cellar/gcc48/4.8.2
--enable-languages=c,c++,objc,obj-c++
--program-suffix=-4.8
--with-gmp=/usr/local/opt/gmp4
--with-mpfr=/usr/local/opt/mpfr2
--with-mpc=/usr/local/opt/libmpc08
--with-cloog=/usr/local/opt/cloog018
--with-isl=/usr/local/opt/isl011
--with-system-zlib
--enable-version-specific-runtime-libs
--enable-libstdcxx-time=yes
--enable-stage1-checking
--enable-checking=release
--enable-lto
--disable-werror
--enable-plugin
--disable-nls
--disable-multilib
Thread model: posix
gcc version 4.8.2 (GCC)
clang 版本
theisenp$ clang++ -v
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.2
Thread model: posix
如评论中所讨论的,重要的是,libprotobuf是与您在编译代码时使用的相同的stdlib编译的,因为libprotobuf在其接口中使用stl类型(尤其是 std::string
)。如果您已经安装了GCC 4.8,它将使用GCC的LibstDC 4.8。与此同时,用Xcode发货的clang将使用任何带有Xcode的stdlibs船,因此即使您告诉它--stdlib=libstdc++
,也可能是一个不兼容的版本。
我怀疑您的问题可能在这里:
int size = original.ByteSize();
char data[size];
可变长度阵列不是有效的C (在C99中允许它们,它们是GCC扩展。
我建议使用动态分配的缓冲区,看看问题是否持续。关于Clang和Vlas的讨论大约在2010年。