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
Description
The destructor of
basic_jsoninvokesjson_value::destroy, which may allocate a largestd::vectorto flatten out its object/array hierarchy in order to avoid recursion. In the event of an allocation failure, the vector will throw an uncatchablestd::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
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
developbranch is used.