Почему экземпляр unique_ptr компилируется в более крупный двоичный код, чем исходный указатель?
Мне всегда казалось, что std::unique_ptr
не имеет накладных расходов по сравнению с использованием необработанного указателя. Однако, компилируя следующий код
#include <memory>
void raw_pointer() {
int* p = new int[100];
delete[] p;
}
void smart_pointer() {
auto p = std::make_unique<int[]>(100);
}
с g++ -std=c++14 -O3
выдает следующую сборку:
raw_pointer():
sub rsp, 8
mov edi, 400
call operator new[](unsigned long)
add rsp, 8
mov rdi, rax
jmp operator delete[](void*)
smart_pointer():
sub rsp, 8
mov edi, 400
call operator new[](unsigned long)
lea rdi, [rax+8]
mov rcx, rax
mov QWORD PTR [rax], 0
mov QWORD PTR [rax+392], 0
mov rdx, rax
xor eax, eax
and rdi, -8
sub rcx, rdi
add ecx, 400
shr ecx, 3
rep stosq
mov rdi, rdx
add rsp, 8
jmp operator delete[](void*)
Почему вывод для smart_pointer()
почти в три раза больше, чем raw_pointer()
?
Ответы
Ответ 1
Поскольку std::make_unique<int[]>(100)
выполняет инициализацию значения, а new int[100]
выполняет инициализация по умолчанию. В первом случае элементы являются 0-инициализированными (для int
), а во втором случае элементы остаются неинициализированными. Попробуйте:
int *p = new int[100]();
И вы получите тот же результат, что и с std::unique_ptr
.
См. this, в котором указано, что std::make_unique<int[]>(100)
эквивалентно:
std::unique_ptr<T>(new int[100]())
Если вам нужен неинициализированный массив с std::unique_ptr
, вы можете использовать 1:
std::unique_ptr<int[]>(new int[100]);
1 Как упоминалось в комментариях @Ruslan, обратите внимание на разницу между std::make_unique()
и std::unique_ptr()
- См. Различия между std:: make_unique и std:: unique_ptr.