C++ C++  ·  25 вопросов  ·  ~70 мин  ·  ⏱ Таймер 10:00  ·  Средний  · 

Память и пользовательские аллокаторы

Тест отделяет выделение сырой памяти от времени жизни объекта. Вопросы охватывают new/delete, placement new, allocator_traits, memory_resource и фрагментацию — с упором на корректное построение, разрушение и измерение реальной пользы.

Отвечено: 0 из 25
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. В тесте 25 вопросов, время — 70 минут. Во многих заданиях недостаточно узнать конструкцию: проследите порядок вычислений, время жизни объектов, владение ресурсами и условия, при которых решение остаётся корректным. После завершения откроются правильные ответы, объяснения, общий результат и тематические шкалы.
Вопрос 1 из 25
Что делает выражение `new T(args...)`?
C++C++20
void* raw = ::operator new(sizeof(Widget));
try {
    Widget* p = std::construct_at(static_cast<Widget*>(raw), config);
    use(*p);
} catch (...) {
    ::operator delete(raw);
    throw;
}
Вопрос 2 из 25
Чем `::operator new(sizeof(T))` отличается от `new T`?
C++C++20
void* storage = ::operator new(sizeof(Widget)); // только сырая память
Widget* object = nullptr;
try {
    object = std::construct_at(static_cast<Widget*>(storage), 42);
} catch (...) {
    ::operator delete(storage);
    throw;
}
Вопрос 3 из 25
Почему `delete[]` обязан соответствовать `new[]`?
C++C++20
Widget* items = new Widget[4];
// ...
delete items;   // неверная парная форма
// delete[] items; // корректная форма
Вопрос 4 из 25
Что произойдёт при обычном `new T` при нехватке памяти?
C++C++20
try {
    auto* block = new LargeTable(1'000'000);
    use(block);
    delete block;
} catch (const std::bad_alloc& error) {
    report_memory_pressure(error);
}
Вопрос 5 из 25
Когда нужна alignment-aware форма allocation function?
C++C++20
struct alignas(64) CacheLine {
    std::byte bytes[64];
};
void* p = ::operator new(
    sizeof(CacheLine),
    std::align_val_t{alignof(CacheLine)}
);
Вопрос 6 из 25
Что делает placement new `new (buffer) T(args...)`?
C++C++20
alignas(Widget) std::byte storage[sizeof(Widget)];

Widget* object = new (storage) Widget(42);
object->run();
object->~Widget();
Вопрос 7 из 25
Как завершить жизнь объекта, созданного placement new, без освобождения внешнего буфера?
C++C++20
alignas(Node) std::byte buffer[sizeof(Node)];
Node* node = std::construct_at(
    reinterpret_cast<Node*>(buffer), 7);

consume(*node);
std::destroy_at(node); // buffer остаётся внешним
Вопрос 8 из 25
Что не так с кодом?
C++C++20
char buffer[sizeof(T)];
T* p = new (buffer) T;
Вопрос 9 из 25
Когда может понадобиться std::launder?
C++C++20
alignas(Node) std::byte storage[sizeof(Node)];
Node* old = std::construct_at(
    reinterpret_cast<Node*>(storage), 1
);
std::destroy_at(old);
Node* current = std::construct_at(
    reinterpret_cast<Node*>(storage), 2
);
// вопрос: какой указатель допустимо использовать дальше?
Вопрос 10 из 25
Почему нельзя вызвать деструктор вручную, а затем позволить обычной области видимости вызвать его снова?
C++C++20
Widget widget;
widget.~Widget();
// конец области видимости позже попытается разрушить widget ещё раз
Вопрос 11 из 25
За что отвечает аллокатор контейнера?
Вопрос 12 из 25
Зачем использовать `std::allocator_traits<A>` вместо прямых вызовов методов A?
C++C++20
template<class Alloc>
void build_one(Alloc& alloc) {
    using Traits = std::allocator_traits<Alloc>;
    auto p = Traits::allocate(alloc, 1);
    try { Traits::construct(alloc, p, 42); }
    catch (...) { Traits::deallocate(alloc, p, 1); throw; }
}
Вопрос 13 из 25
Что даёт `std::pmr::vector<T>`?
C++C++20
std::array<std::byte, 4096> buffer{};
std::pmr::monotonic_buffer_resource arena(buffer.data(), buffer.size());
std::pmr::vector<Record> rows{&arena};

rows.reserve(100);
load(rows);
Вопрос 14 из 25
Когда `std::pmr::monotonic_buffer_resource` особенно полезен?
C++C++20
void handle_request(const Request& request) {
    std::array<std::byte, 32 * 1024> storage{};
    std::pmr::monotonic_buffer_resource arena(storage.data(), storage.size());
    std::pmr::vector<Token> tokens{&arena};
    parse(request.body(), tokens);
} // вся арена освобождается одним действием
Вопрос 15 из 25
Почему перемещение контейнера между разными несовместимыми аллокаторами может потребовать перемещения каждого элемента?
Вопрос 16 из 25
Что такое внешняя фрагментация?
Вопрос 17 из 25
Почему пул фиксированного размера может ускорить создание узлов?
Вопрос 18 из 25
Как уменьшить число мелких аллокаций для множества коротких строк?
Вопрос 19 из 25
Почему compact vector объектов часто лучше vector<unique_ptr<T>> для однородных значений?
Вопрос 20 из 25
Может ли пользовательский аллокатор устранить утечку, вызванную потерянным владельцем?
Вопрос 21 из 25
Что обнаруживает AddressSanitizer?
Вопрос 22 из 25
Как проверить, что пользовательский memory_resource получает правильное выравнивание?
Вопрос 23 из 25
Как измерить эффект monotonic_resource?
Вопрос 24 из 25
Какой тест нужен для exception safety ручного construct/deallocate?
Вопрос 25 из 25
Почему счётчик `operator new` на уровне процесса может вводить в заблуждение?
C++C++20
std::atomic<std::size_t> allocations{0};

void* operator new(std::size_t n) {
    allocations.fetch_add(1, std::memory_order_relaxed);
    if (void* p = std::malloc(n)) return p;
    throw std::bad_alloc{};
}
// Счётчик видит также библиотеки и внутренние аллокации инфраструктуры.

Ответьте на все 25 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу