为什么我的 rapidjson/example/serialize/serialize.cpp 的简化版本会抛出分段错误?

Why is my simplified version of rapidjson/example/serialize/serialize.cpp throwing a segmentation fault?

我正在阻止我已经尝试解决 2 天的问题..

我想使用 rapidjson 和 libpqxx/pistache 到 insert/read json 来自 API 调用/来自数据库的数据。我尝试了一个简单版本的序列化示例只是为了掌握它,但它抛出了一个段错误..

在 linux mint 19 (Tara) 上,我使用 CMake/Make 和 C++17 编译了我的代码(我将相关代码放在 main.cc 中)。

这是文件夹树:

/home/[user]/Documents/algoEngine/library/sources/main.cc /home/[user]/Documents/algoEngine/library/sources/library.cc /home/[user]/Documents/algoEngine/library/headers/library.hh /usr/local/include/rapidjson /usr/local/lib/libpqxx.so /usr/local/lib/libpistache.so

我的 CMakeLists.txt 文件:


    cmake_minimum_required(VERSION 3.10.2)
    project(algoEngine)

    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_EXTENSIONS OFF)

    # fmax-errors => max number of errors displayed at compile time
    # GCC_COMPILE_FLAGS = can append several desired option of gcc. For example: "-fmax-errors=3 -Wall"
    set(GCC_COMPILE_FLAGS "-fmax-errors=3 -g")
    set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COMPILE_FLAGS}")

    # adding preprocessor values..
    add_compile_definitions(RAPIDJSON_HAS_STDSTRING=1)

    #However, the file(GLOB...) allows for wildcard additions:
    file(GLOB SOURCES_LIBRARY "${CMAKE_SOURCE_DIR}/library/sources/*.cc")

    # remove libraryBridge.cc from SOURCES_LIBRARY
    list(REMOVE_ITEM SOURCES_LIBRARY "${CMAKE_SOURCE_DIR}/library/sources/libraryBridge.cc") 

    add_executable(algoLibrary ${SOURCES_LIBRARY})


    target_include_directories(algoLibrary PUBLIC ${CMAKE_SOURCE_DIR}/library/headers)   # might be useless with find_package just below? 

    find_package(RapidJSON)

    target_link_libraries(algoLibrary pistache pqxx)

    set(CMAKE_INSTALL_RPATH "/usr/local/lib")
    set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

    ######################## INSTALL CONFIGURATION ######################## 
    # create conf directory
    set(algoLibraryInstallDir "/usr/local/bin/algoLibrary")

    file(GLOB algoLibraryConfFiles "${CMAKE_SOURCE_DIR}/library/conf/*Library*.conf")

    install(TARGETS algoLibrary DESTINATION ${algoLibraryInstallDir})
    install(FILES ${algoLibraryConfFiles} DESTINATION ${algoLibraryInstallDir}/conf)

我的 main.cc 文件(我将文件修改为只有我想要的测试。通常,我会实例化一个 "Library" class,其中包含一个带有 Pistache 的 http 服务器)


    #include "library.hh"
    // for test purpose, to remove..
    #include "rapidjson/document.h"
    #include "rapidjson/stringbuffer.h"
    #include "rapidjson/prettywriter.h"
    #include "rapidjson/writer.h"

    using namespace std;
    using namespace rapidjson;

    int main(int argc, char* argv[]) {
      const char* json = "{\"address\":\"127.0.0.1\", \"port\":9100}";
      Document doc;
      doc.Parse(json);

      StringBuffer jsonBuffer;
      Writer<StringBuffer> jsonWriter;

      doc.Accept(jsonWriter);

      std::cout << "output json is : " << jsonBuffer.GetString() << endl;
      return 0;
    }

当我执行程序时程序进入段错误。 我尝试用 GDB 执行,这里是输出:

gdb /usr/local/bin/algoLibrary/algoLibrary 
... Reading symbols from
/usr/local/bin/algoLibrary/algoLibrary...done. (gdb) b main Breakpoint 1 at 0x2ad46: file
/home/farouk/Documents/algoEngine/library/sources/main.cc, line 11.
(gdb) r 
Starting program: /usr/local/bin/algoLibrary/algoLibrary 
[Thread debugging using libthread_db enabled] Using host libthread_db
library "/lib/x86_64-linux-gnu/libthread_db.so.1". 
n
Breakpoint 1, main (argc=1, argv=0x7fffffffe468) at
/home/farouk/Documents/algoEngine/library/sources/main.cc:11 11 int main(int argc, char* argv[]) { 
(gdb) n 
28    const char* json =
"{\"address\":\"127.0.0.1\", \"port\":9100}"; 
(gdb)  
29    Document doc; 
(gdb)  
30    doc.Parse(json); 
(gdb)  
32    StringBuffer jsonBuffer;
(gdb)  
33    Writer<StringBuffer> jsonWriter; 
(gdb)  
35   
doc.Accept(jsonWriter); (gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x000055555556e2d0 in
rapidjson::internal::Stack<rapidjson::CrtAllocator>::Reserve<char>
(this=0x0, count=1) at
/usr/local/include/rapidjson/internal/stack.h:118 118           if(RAPIDJSON_UNLIKELY(static_cast<std::ptrdiff_t>(sizeof(T) * count) (stackEnd_ - stackTop_)))

好的,通过逐行比较我的代码与 rapidjson/example/serialize/serialize.cpp:

中的示例,我终于找到了我的问题

在实例化 rapidjson::Writer(或 PrettyWritter)时,您需要使用 StringBuffer 作为参数调用其构造函数。我的代码将变为:

    int main(int argc, char* argv[]) {
  const char* json = "{\"address\":\"127.0.0.1\", \"port\":9100}";
  Document doc;
  doc.Parse(json);

  StringBuffer jsonBuffer;
  Writer<StringBuffer> jsonWriter(jsonBuffer);  // Update is here: give jsonBuffer to jsonWriter

  doc.Accept(jsonWriter);

  std::cout << "output json is : " << jsonBuffer.GetString() << endl;
  return 0;
}