As discussed in comments, it's important that libprotobuf is compiled with the same stdlib that you use when compiling your code, since libprotobuf uses STL types (especially std::string
) in its interface. If you've installed GCC 4.8, it will use GCC's libstdc++ 4.8. The Clang shipped with Xcode, meanwhile, will use whatever stdlibs ship with Xcode, so even if you tell it --stdlib=libstdc++
, it may be an incompatible version.
Simple Protocol Buffers program works when compiled with g++ but not clang++
-
04-10-2022 - |
Question
I'm trying to use protocol buffers in a simple C++ program. When I compile with g++
the program executes and exits normally. When I compile with clang++
the program fails, complaining that pointer being freed was not allocated
.
Protocol Buffer Message Definition
package test;
message Test {
required int32 id = 1;
required string name = 2;
}
Main Class
#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++ Output
theisenp$ g++ test.pb.cc main.cpp -lprotobuf -o g++.out
theisenp$ ./g++.out
0: original
0: original
clang++ Output
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
I'm new to both Protocol Buffers and Clang so it's entirely possible that I'm missing something obvious. Any ideas?
Edit
Some clarification on compiler versions. I'm running OSX Mavericks (10.9.1). By default, Mavericks maps calls to gcc
and g++
to clang
and clang++
respectively. I've installed gcc
4.8.2 independently and overridden the default behavior.
g++ Version
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++ Version
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
Solution
OTHER TIPS
I suspect your problem may be here:
int size = original.ByteSize();
char data[size];
Variable length arrays are not valid C++ (they are permitted in C99), they are a GCC extension.
I'd suggest using a dynamically allocated buffer and see if the problem persists. There is some discussion about clang and VLAs circa 2010 here.