Skip to content

basic_json destructor allocates memory, violating noexcept semantics #5135

@EvanBalster

Description

@EvanBalster

Description

The destructor of basic_json invokes json_value::destroy, which may allocate a large std::vector to flatten out its object/array hierarchy in order to avoid recursion. In the event of an allocation failure, the vector will throw an uncatchable std::bad_alloc, terminating the program.

(I noticed this while debugging a related issue, where destroying an invalidated JSON object caused a four-exabyte allocation.)

Reproduction steps

  • Create a complex JSON document by nesting a few million arrays/objects in an arbitrary structure.
  • Artificially exhaust the application's available memory.
  • Destroy your JSON document.

Expected vs. actual results

Allocating a bunch of memory in a destructor is weird and widely understood to be unsafe.

Normal recursive destruction would be suitable for my use-case. If that is unacceptable, there are methods (such as forming an ad-hoc linked list) that could be used to avoid recursion without allocating. If those methods are unacceptable, a non-throwing allocator could be used with a fallback to recursive destruction in the event that no memory is available.

The latter approach is implemented by PR #4654.

Minimal code example

Error messages

Compiler and operating system

Win11/MSVC

Library 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