# memory\_resource

***

**1. Allocating Memory for a Vector**

```cpp
#include <vector>
#include <memory_resource>

int main() {
  // Create a memory resource
  std::pmr::memory_resource* mr = std::pmr::get_default_resource();

  // Allocate a vector using the memory resource
  std::vector<int, std::pmr::polymorphic_allocator<int>> vec(mr);

  // Push back elements to the vector
  vec.push_back(1);
  vec.push_back(2);
  vec.push_back(3);

  // Print the vector
  for (int i : vec) {
    std::cout << i << " ";
  }

  return 0;
}
```

**2. Allocating Memory for a String**

```cpp
#include <string>
#include <memory_resource>

int main() {
  // Create a memory resource
  std::pmr::memory_resource* mr = std::pmr::get_default_resource();

  // Allocate a string using the memory resource
  std::string str(mr);

  // Append characters to the string
  str.append("Hello");
  str.append(" World");

  // Print the string
  std::cout << str << std::endl;

  return 0;
}
```

**3. Allocating Memory for a Class**

```cpp
#include <memory>
#include <memory_resource>

class MyClass {
public:
  MyClass() { std::cout << "MyClass constructor called" << std::endl; }
  ~MyClass() { std::cout << "MyClass destructor called" << std::endl; }
};

int main() {
  // Create a memory resource
  std::pmr::memory_resource* mr = std::pmr::get_default_resource();

  // Allocate a class using the memory resource
  auto ptr = std::pmr::allocate<MyClass>(mr);

  // Access the class
  ptr->method();

  // Deallocate the class
  std::pmr::deallocate(ptr, sizeof(MyClass), mr);

  return 0;
}
```

**4. Allocating Memory for an Array**

```cpp
#include <memory_resource>

int main() {
  // Create a memory resource
  std::pmr::memory_resource* mr = std::pmr::get_default_resource();

  // Allocate an array using the memory resource
  int* arr = static_cast<int*>(std::pmr::allocate(mr, sizeof(int) * 10));

  // Access the array
  arr[0] = 1;
  arr[1] = 2;
  arr[2] = 3;

  // Deallocate the array
  std::pmr::deallocate(arr, sizeof(int) * 10, mr);

  return 0;
}
```

**5. Allocating Memory for a Custom Allocator**

```cpp
#include <memory_resource>

class MyAllocator : public std::pmr::memory_resource {
public:
  void* allocate(size_t size, size_t alignment) override {
    // Implement your own allocation logic here
    return nullptr;
  }

  void deallocate(void* ptr, size_t size, size_t alignment) override {
    // Implement your own deallocation logic here
    return;
  }
};

int main() {
  // Create a custom allocator
  MyAllocator allocator;

  // Allocate memory using the custom allocator
  void* ptr = allocator.allocate(1024, 64);

  // Deallocate memory using the custom allocator
  allocator.deallocate(ptr, 1024, 64);

  return 0;
}
```

**6. Allocating Memory for a PMR Vector**

```cpp
#include <vector>
#include <memory_resource>

int main() {
  // Create a PMR vector
  std::pmr::vector<int> vec(std::pmr::get_default_resource());

  // Push back elements to the vector
  vec.push_back(1);
  vec.push_back(2);
  vec.push_back(3);

  // Print the vector
  for (int i : vec) {
    std::cout << i << " ";
  }

  return 0;
}
```

**7. Allocating Memory for a PMR String**

```cpp
#include <string>
#include <memory_resource>

int main() {
  // Create a PMR string
  std::pmr::string str(std::pmr::get_default_resource());

  // Append characters to the string
  str.append("Hello");
  str.append(" World");

  // Print the string
  std::cout << str << std::endl;

  return 0;
}
```

**8. Allocating Memory for a PMR Class**

```cpp
#include <memory>
#include <memory_resource>

class MyClass {
public:
  MyClass() { std::cout << "MyClass constructor called" << std::endl; }
  ~MyClass() { std::cout << "MyClass destructor called" << std::endl; }
};

int main() {
  // Create a PMR class
  auto ptr = std::pmr::allocate<MyClass>(std::pmr::get_default_resource());

  // Access the class
  ptr->method();

  // Deallocate the class
  std::pmr::deallocate(ptr, sizeof(MyClass), std::pmr::get_default_resource());

  return 0;
}
```

**9. Allocating Memory for a PMR Array**

```cpp
#include <memory_resource>

int main() {
  // Allocate an array using a PMR allocator
  int* arr = static_cast<int*>(std::pmr::allocate(std::pmr::get_default_resource(), sizeof(int) * 10));

  // Access the array
  arr[0] = 1;
  arr[1] = 2;
  arr[2] = 3;

  // Deallocate the array
  std::pmr::deallocate(arr, sizeof(int) * 10, std::pmr::get_default_resource());

  return 0;
}
```

**10. Allocating Memory for a PMR Custom Allocator**

```cpp
#include <memory_resource>

class MyAllocator : public std::pmr::memory_resource {
public:
  void* allocate(size_t size, size_t alignment) override {
    // Implement your own allocation logic here
    return nullptr;
  }

  void deallocate(void* ptr, size_t size, size_t alignment) override {
    // Implement your own deallocation logic here
    return;
  }
};

int main() {
  // Create a PMR custom allocator
  std::pmr::memory_resource* mr = new MyAllocator();

  // Allocate memory using the PMR custom allocator
  void* ptr = mr->allocate(1024, 64);

  // Deallocate memory using the PMR custom allocator
  mr->deallocate(ptr, 1024, 64);

  return 0;
}
```

**11. Using a Memory Resource for a Custom Memory Pool**

```cpp
#include <memory_resource>

class MyMemoryPool : public std::pmr::memory_resource {
public:
  // Allocate a block of memory from the pool
  void* allocate(size_t size, size_t alignment) override {
    // Implement pool allocation logic here
    return nullptr;
  }

  // Deallocate a block of memory from the pool
  void deallocate(void* ptr, size_t size, size_t alignment) override {
    // Implement pool deallocation logic here
    return;
  }
};

int main() {
  // Create a custom memory pool
  MyMemoryPool pool;

  // Allocate memory using the memory pool
  void* ptr = pool.allocate(1024, 64);

  // Deallocate memory using the memory pool
  pool.deallocate(ptr, 1024, 64);

  return 0;
}
```

**12. Using a Memory Resource for Thread-Safe Memory Allocation**

```cpp
#include <memory_resource>
#include <thread>

std::pmr::memory_resource* mr = std::pmr::get_default_resource();

void threadFunction() {
  // Allocate memory using the memory resource in a thread-safe manner
  void* ptr = mr->allocate(1024, 64);

  // Deallocate memory using the memory resource in a thread-safe manner
  mr->deallocate(ptr, 1024, 64);
}

int main() {
  // Create multiple threads that allocate and deallocate memory using the memory resource
  std::vector<std::thread> threads;
  for (int i = 0; i < 10; i++) {
    threads.push_back(std::thread(threadFunction));
  }

  for (auto& thread : threads) {
    thread.join();
  }

  return 0;
}
```

**13. Using a Memory Resource for Heap Monitoring**

```cpp
#include <memory_resource>
#include <iostream>

class LoggingMemoryResource : public std::pmr::memory_resource {
public:
  // Called when memory is allocated
  void* allocate(size_t size, size_t alignment) override {
    std::cout << "Allocated " << size << " bytes at " << (void*)ptr << std::endl;
    return ptr;
  }

  // Called when memory is deallocated
  void deallocate(void* ptr, size_t size, size_t alignment) override {
    std::cout << "Deallocated " << size << " bytes at " << ptr << std::endl;
    return;
  }
};

int main() {
  // Create a logging memory resource
  LoggingMemoryResource mr;

  // Allocate memory using the logging memory resource
  void* ptr = mr.allocate(1024, 64);

  // Deallocate memory using the logging memory resource
  mr.deallocate(ptr, 1024, 64);

  return 0;
}
```

**14. Using a Memory Resource for Memory Limit Checking**

```cpp
#include <memory_resource>

class LimitCheckingMemoryResource : public std::pmr::memory_resource {
public:
  // Allocate memory and check if it exceeds the limit
  void* allocate(size_t size, size_t alignment) override {
    if ((_allocated + size) > _limit) {
      throw std::bad_alloc();
    }

    _allocated += size;
    return ptr;
  }

private:
  size_t _allocated = 0;
  size_t _limit = 1024 * 1024;  // 1MB limit
};

int main() {
  // Create a limit checking memory resource
  LimitCheckingMemoryResource mr;

  // Try to allocate memory that exceeds the limit
  try {
    void* ptr = mr.allocate(1024 * 1024 + 1, 64);
  } catch (std::bad_alloc& e) {
    std::cout << "Allocation failed: " << e.what() << std::endl;
  }

  return 0;
}
```

**15. Using a Memory Resource for Resource Acquisition Is Initialization (RAII)**

```cpp
#include <memory_resource>

class MyResource {
public:
  MyResource(std::pmr::memory_resource* mr) : _ptr(mr->allocate(1024, 64)) {}
  ~MyResource() { std::pmr::deallocate(_ptr, 1024, 64); }

private:
  void* _ptr;
};

int main() {
  // Create a memory resource
  std::pmr::memory_resource* mr = std::pmr::get_default_resource();

  {
    // Create a MyResource object that will be automatically deallocated when it goes out of scope
    MyResource resource(mr);
  }

  return 0;
}
```

**16. Using a Memory Resource for Custom Memory Management**

```cpp
#include <memory_resource>
#include <vector>

class MyMemoryManager : public std::pmr::memory_resource {
public:
  // Allocate memory and store it in a custom data structure
  void* allocate(size_t size, size_t alignment) override {
    void* ptr = malloc(size);
    _allocated.push_back(ptr);
    return ptr;
  }

  // Deallocate memory from the custom data structure
  void deallocate(void* ptr, size_t size, size_t alignment) override {
    for (auto it = _allocated.begin(); it != _allocated.end(); it++) {
      if (*it == ptr) {
        _allocated.erase(it);
        break;
      }
    }

    free(ptr);
  }

private:
  std::vector<void*> _allocated;


```
