C++20stladvanced
std::make_shared_for_overwrite / std::make_unique_for_overwrite (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Create smart pointers with default-initialized (not value-initialized) storage. For trivial types, this leaves memory uninitialized, avoiding the cost of zeroing when you intend to overwrite the contents immediately.
Real-World Scenario
Allocate a large buffer for file I/O where the contents will be completely overwritten by a read operation, saving the cost of zero-initialization.
Quick Snippet
snippet.cpp
#include <memory>
// Value-initialized (zeroed): expensive for large arrays
auto zeroed = std::make_unique<char[]>(1'000'000);
// Default-initialized (uninitialized): faster
auto buffer = std::make_unique_for_overwrite<char[]>(1'000'000);
// Fill buffer from file:
// file.read(buffer.get(), 1'000'000);
auto shared_buf = std::make_shared_for_overwrite<double[]>(1024);Full Example
make_for_overwrite.cpp
// CodeNebula - C++20 Example: make_shared_for_overwrite and make_unique_for_overwrite
// Compile: g++ -std=c++20 -Wall -Wextra -o example make_for_overwrite.cpp
#include <iostream>
#include <memory>
#include <cstring>
int main() {
std::cout << "=== std::make_unique_for_overwrite ===\n";
// make_unique<T>() value-initializes (zeros for built-in types)
// make_unique_for_overwrite<T>() default-initializes (indeterminate for built-in)
// Useful when you plan to overwrite the memory immediately
// Single object
auto p1 = std::make_unique_for_overwrite<int>();
*p1 = 42; // Overwrite immediately
std::cout << "unique_ptr single: " << *p1 << "\n";
// Array of objects - no zero-initialization overhead
constexpr std::size_t N = 10;
auto arr = std::make_unique_for_overwrite<int[]>(N);
// Fill with data (the whole point: we write before reading)
for (std::size_t i = 0; i < N; ++i) {
arr[i] = static_cast<int>(i * i);
}
std::cout << "unique_ptr array: ";
for (std::size_t i = 0; i < N; ++i) std::cout << arr[i] << " ";
std::cout << "\n";
std::cout << "\n=== std::make_shared_for_overwrite ===\n";
// Single object
auto sp1 = std::make_shared_for_overwrite<double>();
*sp1 = 3.14;
std::cout << "shared_ptr single: " << *sp1 << "\n";
std::cout << "Use count: " << sp1.use_count() << "\n";
// Array (C++20 shared_ptr supports arrays)
auto sarr = std::make_shared_for_overwrite<char[]>(64);
std::strcpy(sarr.get(), "Hello, C++20!");
std::cout << "shared_ptr array: " << sarr.get() << "\n";
std::cout << "\n=== Comparison with value-initialized versions ===\n";
// make_unique<int>() guarantees zero-initialization
auto zeroed = std::make_unique<int>();
std::cout << "make_unique<int>(): " << *zeroed << " (guaranteed 0)\n";
// make_unique_for_overwrite<int>() has indeterminate value
auto uninitialized = std::make_unique_for_overwrite<int>();
*uninitialized = 99; // Must write before reading!
std::cout << "make_unique_for_overwrite<int>(): " << *uninitialized
<< " (after assignment)\n";
std::cout << "\n=== Performance benefit scenario ===\n";
// Large buffer: skipping zero-init saves time
constexpr std::size_t BUF_SIZE = 1024 * 1024;
auto buffer = std::make_unique_for_overwrite<unsigned char[]>(BUF_SIZE);
// Simulate filling from I/O (just memset here)
std::memset(buffer.get(), 0xAB, BUF_SIZE);
std::cout << "1MB buffer created without zero-init overhead\n";
std::cout << "First byte: 0x" << std::hex
<< static_cast<int>(buffer[0]) << "\n";
std::cout << "Last byte: 0x"
<< static_cast<int>(buffer[BUF_SIZE - 1]) << "\n";
return 0;
}
Run command
g++ -std=c++20 -Wall -Wextra -o example make_for_overwrite.cpp