Skip to content

Allocator Propagation Issues with std::pmr in nlohmann::json: Limitations #4810

@ankitghevariya

Description

@ankitghevariya

Description

I was trying to use the library with std::pmr support by replacing the internal containers with std::pmr::map and std::pmr::vector. Initially, I faced compilation errors because std::map and std::pmr::map have different template parameters (due to different allocators). To work around this, I created template aliases matching the expected signature, which allowed the code to compile.

However, when I tried adding values to the JSON object, I encountered a static assertion failure. After investigating, I found that basic_json does not provide a constructor that accepts an allocator, unlike other standard containers. As a result, the internal PMR containers are default-constructed without a proper allocator, which causes allocator mismatch errors during compile operations like insertions.

This is a high-priority issue

Reproduction steps

Just compile the attached minimal code example.

g++ -std=c++17 -o pmr_json pmr_json.cpp

Expected vs. actual results

Expected:
After configuring basic_json with std::pmr-compatible containers and strings, I expected to be able to construct and use JSON objects with custom memory resources (e.g., std::pmr::monotonic_buffer_resource) without errors. Specifically, I expected that:

  • Allocator-aware containers inside basic_json would receive the supplied std::pmr::polymorphic_allocator.
  • Operations like assignment (obj["key"] = value) would work as with the default basic_json, but using the custom allocator.

Actual:

  • While compilation succeeded with compatible template aliases, runtime operations on the JSON object failed with a static assertion or allocator mismatch errors.
  • The root cause is that basic_json does not propagate the allocator to internal containers. It default-constructs internal members (e.g., map, vector, string) without using the provided polymorphic_allocator, leading to static assertion.

Note:
PMR support would be very helpful for controlling memory usage more precisely, especially in performance-critical or embedded applications. Having a clear path or official support for std::pmr with basic_json would make integration much smoother.

Minimal code example

#include <iostream>
#include <memory_resource>
#include <nlohmann/json.hpp>

// Template alias to pass polymorphic allocators to nlohmann::json
#if 1
template<typename Key, typename T, typename Ignored, typename Allocator>
using pmr_compatible_map = std::map<Key, T, std::less<Key>, Allocator>;

template<typename T, typename Allocator>
using pmr_compatible_vector = std::vector<T, Allocator>;

using pmr_string = std::basic_string<char, std::char_traits<char>, std::pmr::polymorphic_allocator<char>>;
#endif

using json_pmr = nlohmann::basic_json<
    pmr_compatible_map,
    pmr_compatible_vector,
    pmr_string,
    bool,
    int64_t,
    uint64_t,
    double,
    std::pmr::polymorphic_allocator>;

int main()
{
    std::pmr::monotonic_buffer_resource arena(10240);
    std::pmr::polymorphic_allocator<char> alloc(&arena);

    // Create a polymorphic string using the allocator
    pmr_string str(alloc);
    str = "Hello, PMR world!";
    std::cout << str << std::endl;

    json_pmr obj;
    obj["name"] = "Ankit Ghevariya";  // ❌ Static assertion failure here: no allocator was passed to the object

    return 0;
}

Error messages

Note: The full error message is quite large, so I'm not pasting it here. I've attached a screenshot showing the last lines of the error output for reference.
Image

Compiler and operating system

  • OS: Ubuntu 24.04.2 LTS
  • Compiler: GCC 13.3.0 (g++ (Ubuntu 13.3.0-6ubuntu2~24.04))
  • C++ Standard: C++17 (-std=c++17)

Library version

  • nlohmann/json version: 3.12.0

Validation

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions