99constexpr std::size_t max_allocations = 20'000 ;
1010void * allocations[max_allocations];
1111void * allocations_array[max_allocations];
12- std::size_t num_allocations = 0u ;
13- std::size_t double_delete = 0u ;
14- bool memory_tracking = false ;
12+ std::size_t num_allocations = 0u ;
13+ std::size_t double_delete = 0u ;
14+ bool memory_tracking = false ;
15+ bool force_allocation_failure = false ;
1516
1617#if defined(OUP_PLATFORM_OSX)
1718// Getting weird errors on MacOS when overriding operator new and delete,
@@ -27,6 +28,10 @@ void* allocate(std::size_t size, bool array) {
2728 throw std::bad_alloc ();
2829 }
2930
31+ if (force_allocation_failure) {
32+ throw std::bad_alloc ();
33+ }
34+
3035 void * p = std::malloc (size);
3136 if (!p) {
3237 throw std::bad_alloc ();
@@ -277,6 +282,24 @@ TEST_CASE("owner acquiring constructor", "[owner_construction]") {
277282 REQUIRE (mem_track.double_del () == 0u );
278283}
279284
285+ TEST_CASE (" owner acquiring constructor bad alloc" , " [owner_construction]" ) {
286+ memory_tracker mem_track;
287+
288+ {
289+ test_object* raw_ptr = new test_object;
290+ try {
291+ force_allocation_failure = true ;
292+ test_ptr{raw_ptr};
293+ } catch (...) {
294+ }
295+ force_allocation_failure = false ;
296+ }
297+
298+ REQUIRE (instances == 0 );
299+ REQUIRE (mem_track.leaks () == 0u );
300+ REQUIRE (mem_track.double_del () == 0u );
301+ }
302+
280303TEST_CASE (" owner acquiring constructor with deleter" , " [owner_construction]" ) {
281304 memory_tracker mem_track;
282305
@@ -294,6 +317,24 @@ TEST_CASE("owner acquiring constructor with deleter", "[owner_construction]") {
294317 REQUIRE (mem_track.double_del () == 0u );
295318}
296319
320+ TEST_CASE (" owner acquiring constructor with deleter bad alloc" , " [owner_construction]" ) {
321+ memory_tracker mem_track;
322+
323+ {
324+ test_object* raw_ptr = new test_object;
325+ try {
326+ force_allocation_failure = true ;
327+ test_ptr_with_deleter{raw_ptr, test_deleter{42 }};
328+ } catch (...) {
329+ }
330+ force_allocation_failure = false ;
331+ }
332+
333+ REQUIRE (instances == 0 );
334+ REQUIRE (mem_track.leaks () == 0u );
335+ REQUIRE (mem_track.double_del () == 0u );
336+ }
337+
297338TEST_CASE (" owner acquiring constructor null" , " [owner_construction]" ) {
298339 memory_tracker mem_track;
299340
@@ -1278,6 +1319,28 @@ TEST_CASE("owner reset to new", "[owner_utility]") {
12781319 REQUIRE (mem_track.double_del () == 0u );
12791320}
12801321
1322+ TEST_CASE (" owner reset to new bad alloc" , " [owner_utility]" ) {
1323+ memory_tracker mem_track;
1324+
1325+ {
1326+ test_object* raw_ptr1 = new test_object;
1327+ test_object* raw_ptr2 = new test_object;
1328+ test_ptr ptr (raw_ptr1);
1329+ try {
1330+ force_allocation_failure = true ;
1331+ ptr.reset (raw_ptr2);
1332+ } catch (...) {
1333+ }
1334+ force_allocation_failure = false ;
1335+ REQUIRE (instances == 1 );
1336+ REQUIRE (ptr.get () == raw_ptr1);
1337+ }
1338+
1339+ REQUIRE (instances == 0 );
1340+ REQUIRE (mem_track.leaks () == 0u );
1341+ REQUIRE (mem_track.double_del () == 0u );
1342+ }
1343+
12811344TEST_CASE (" owner reset to new with deleter" , " [owner_utility]" ) {
12821345 memory_tracker mem_track;
12831346
0 commit comments