

- Главная
- Каталог
- Интернет технологии
- C/C++ | Вопросы собесов
C/C++ | Вопросы собесов
Разбираем вопросы с собеседований на С/С++ разработчика
Статистика канала
Полная статистикаchevron_rightstd::string) хранятся в непрерывном буфере (массиве символов), что даёт быстрый доступ по индексу и эффективную работу с кешем. Но если строка будет реализована на связанном списке (std::list<char>), это изменит её свойства.
std::string это O(n) (нужно двигать символы), в std::list<char> – O(1) (добавление элемента в связный список).
std::list<char> может быть полезен, если динамическое изменение памяти важнее экономии места.
std::list<char> доступ к str[1000] требует прохода 1000 элементов (O(n)), а в std::string – просто O(1).
std::list<char> расходует дополнительные 8–16 байт на каждый символ (из-за указателей).
std::string использует непрерывную память, что намного эффективнее.
std::string использует small string optimization (SSO), поэтому маленькие строки хранятся прямо внутри объекта (без динамического выделения памяти).
Ставь 👍 и забирай 📚 Базу знанийtry-catch), либо передано дальше.
#include <iostream>
#include <stdexcept>
class MyClass {
public:
MyClass() {
std::cout << "Конструктор\n";
throw std::runtime_error("Ошибка в конструкторе!");
}
~MyClass() {
std::cout << "Деструктор\n";
}
};
int main() {
try {
MyClass obj; // Попытка создать объект
} catch (const std::exception& e) {
std::cout << "Поймано исключение: " << e.what() << '\n';
}
}{}
Вывод программы
Конструктор
Поймано исключение: Ошибка в конструкторе!{}
#include <iostream>
#include <memory>
#include <stdexcept>
class MyClass {
private:
std::unique_ptr<int> data; // Умный указатель RAII
public:
MyClass() : data(std::make_unique<int>(42)) {
throw std::runtime_error("Ошибка!");
}
};
int main() {
try {
MyClass obj;
} catch (const std::exception& e) {
std::cout << "Ошибка: " << e.what() << '\n';
}
}{}
class MyClass {
public:
MyClass() {
try {
throw std::runtime_error("Ошибка!");
} catch (...) {
std::cout << "Ошибка обработана, объект создан\n";
}
}
};{}
noexcept:
class SafeClass {
public:
SafeClass() noexcept {
std::cout << "Конструктор без исключений\n";
}
};{}
Ставь 👍 и забирай 📚 Базу знанийstd::back_inserter — это адаптер итератора из библиотеки STL, который позволяет удобно добавлять элементы в конец контейнера при использовании алгоритмов стандартной библиотеки (например, std::copy, std::transform и т. д.).
Он создает итератор-вставку (inserter iterator), который при попытке записи нового элемента фактически вызывает метод push_back() у контейнера.
back_inserter позволяет избежать этого ограничения, автоматически расширяя контейнер по мере необходимости.
back_inserter (приведет к ошибке!)
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> source = {1, 2, 3, 4, 5};
std::vector<int> destination; // Пустой контейнер
// Ошибка! У destination нет места для элементов
std::copy(source.begin(), source.end(), destination.begin());
return 0;
}{}
Используем back_inserter (правильный вариант)
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<int> source = {1, 2, 3, 4, 5};
std::vector<int> destination; // Начинаем с пустого контейнера
// Используем back_inserter
std::copy(source.begin(), source.end(), std::back_inserter(destination));
// Вывод результата
for (int num : destination) {
std::cout << num << " ";
}
return 0;
}{}
Вывод
1 2 3 4 5{}
std::transform – Преобразование элементов**
Применяем функцию ко всем элементам и добавляем результат в новый контейнер
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<int> nums = {1, 2, 3, 4, 5};
std::vector<int> squared;
std::transform(nums.begin(), nums.end(), std::back_inserter(squared),
[](int x) { return x * x; });
for (int num : squared) {
std::cout << num << " ";
}
return 0;
}{}
Вывод:
1 4 9 16 25{}
std::unique_copy – Удаление дубликатов
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<int> nums = {1, 2, 2, 3, 4, 4, 5};
std::vector<int> unique_nums;
std::unique_copy(nums.begin(), nums.end(), std::back_inserter(unique_nums));
for (int num : unique_nums) {
std::cout << num << " ";
}
return 0;
}{}
Вывод:
1 2 3 4 5{}
Ставь 👍 и забирай 📚 Базу знанийplacement new – это специальная форма оператора new, которая размещает объект в уже выделенной памяти вместо того, чтобы выделять её заново.
placement new
НЕ выделяет память (мы сами передаём адрес).
Просто вызывает конструктор в указанном месте.
void* ptr = malloc(sizeof(int)); // Выделяем память вручную
int* num = new(ptr) int(42); // Размещаем объект в этой памяти{}
Синтаксис placement new
new (адрес) Type(аргументы конструктора);{}
адрес – указатель на уже выделенную память.
Type(аргументы конструктора) – объект создаётся в этом месте.
#include <iostream>
int main() {
char buffer[sizeof(int)]; // Буфер памяти (размер как у int)
int* p = new (buffer) int(123); // Размещаем int в этом буфере
std::cout << "Значение: " << *p << std::endl; // 123
}{}
new и delete.
char buffer[100]), в shared memory, или в выделенной заранее области (malloc).
std::vector использует placement new внутри себя!
placement new вызывает его конструктор в выделенной памяти.
#include <iostream>
#include <cstdlib> // Для malloc/free
class MyClass {
public:
int x;
MyClass(int val) : x(val) { std::cout << "Конструктор!\n"; }
~MyClass() { std::cout << "Деструктор!\n"; }
};
int main() {
void* buffer = malloc(sizeof(MyClass)); // Выделяем сырую память
MyClass* obj = new (buffer) MyClass(42); // Размещаем объект
std::cout << "Значение: " << obj->x << std::endl;
obj->~MyClass(); // Ручной вызов деструктора!
free(buffer); // Освобождаем память
}{}
Вывод
Конструктор!
Значение: 42
Деструктор!{}
MyClass* obj = new (buffer) MyClass(10);
// delete obj; // НЕЛЬЗЯ! Обычный `delete` не работает
free(buffer); // Память утекла! Деструктор не вызвался{}
Нужно вызвать вручную
obj->~MyClass();
free(buffer);{}
placement new в одном буфере несколько раз (без очистки)*
void* buffer = malloc(sizeof(MyClass));
MyClass* obj1 = new (buffer) MyClass(1);
MyClass* obj2 = new (buffer) MyClass(2); // Перезапишет obj1!{}
Нужно сначала вызвать деструктор
obj1->~MyClass();
MyClass* obj2 = new (buffer) MyClass(2);{}
Освободил память перед вызовом деструктора
free(buffer); // Память освободили
obj->~MyClass(); // ОШИБКА! Память уже не существует{}
Правильный порядок
obj->~MyClass();
free(buffer);{}
Ставь 👍 и забирай 📚 Базу знанийОтзывы канала
- Добавлен: Сначала новые
- Добавлен: Сначала старые
- Оценка: По убыванию
- Оценка: По возрастанию
Каталог Телеграм-каналов для нативных размещений
C/C++ | Вопросы собесов — это Telegam канал в категории «Интернет технологии», который предлагает эффективные форматы для размещения рекламных постов в Телеграмме. Количество подписчиков канала в 4.3K и качественный контент помогают брендам привлекать внимание аудитории и увеличивать охват. Рейтинг канала составляет 5.2, количество отзывов – 1, со средней оценкой 5.0.
Вы можете запустить рекламную кампанию через сервис Telega.in, выбрав удобный формат размещения. Платформа обеспечивает прозрачные условия сотрудничества и предоставляет детальную аналитику. Стоимость размещения составляет 4615.38 ₽, а за 3 выполненных заявок канал зарекомендовал себя как надежный партнер для рекламы в TG. Размещайте интеграции уже сегодня и привлекайте новых клиентов вместе с Telega.in!
Вы снова сможете добавить каналы в корзину из каталога
Комментарий