那是你見識太少了。問你兩個問題,不求你能回答,但至少求你能看的懂問題。
1. SIMD 中不少指令是要求數據對齊的,請問要是對齊要求超過了 malloc/new 預設的對齊了,你打算怎麽辦?
對齊版本的 operator new 多載了解一下?
void
*
operator
new
(
std
::
size_t
count
,
std
::
align_val_t
al
);
2. new 申請不到記憶體時,在預設情況下,是會一個迴圈,不斷呼叫 std::get_new_handler 返回的函式指標,直到分配成功為止的。我覺得這也太坑了,頂多試三次就行了,你打算怎麽辦?
把你程式碼裏出現 new 的地方全一個一個替換掉麽?累死你。
你說用不到這個功能,那是因為都給你封裝在底層了,不需要來讓你操心了。
我跟你說,要是沒多載 new 這個功能,你連最基礎的 vector 都實作不了。
vector 最核心的需求是什麽?是要求記憶體分配和物件的構造之間能解耦、解分配和物件的析構之間能解耦。說人話,就是需要先用 allocator.allocate() 方法從分配器中提前分配出記憶體塊, 等推遲到合適的時候,才在這個記憶體塊上構造出物件 。
那些叫囂 100 行寫出的 vector,其實作都是根本不能用的,裏面全是用的 new T[]。
正規的寫法必須要用到 placement new —— 這是多載 new 的最機智的利用。
vector 的基本原理如下:
#include
<new>
#include
<iostream>
struct
Foo
{
int
i
;
Foo
(
int
i
)
:
i
(
i
)
{
std
::
cout
<<
"構造 "
<<
i
<<
std
::
endl
;
}
~
Foo
()
{
std
::
cout
<<
"析構 "
<<
i
<<
std
::
endl
;
}
};
int
main
()
{
std
::
allocator
<
Foo
>
alloc
;
Foo
*
p
=
alloc
.
allocate
(
3
);
std
::
cout
<<
"分配好緩沖區了"
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
std
::
cout
<<
"push_back 第 "
<<
i
<<
" 個元素"
<<
std
::
endl
;
new
(
p
+
i
)
Foo
(
i
);
}
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
std
::
cout
<<
"pop_back 第 "
<<
i
<<
" 個元素"
<<
std
::
endl
;
(
p
+
2
-
i
)
->~
Foo
();
}
alloc
.
deallocate
(
p
,
3
);
std
::
cout
<<
"釋放完緩沖區了"
<<
std
::
endl
;
}
輸出:
分配好緩沖區了
push_back 第 0 個元素
構造 0
push_back 第 1 個元素
構造 1
push_back 第 2 個元素
構造 2
pop_back 第 0 個元素
析構 2
pop_back 第 1 個元素
析構 1
pop_back 第 2 個元素
析構 0
釋放完緩沖區了
你以為 placement new 是 C++ 為其特殊設計的語法?
不是的,placement new 只是一個函式呼叫而已。它只不過是:
void
*
operator
new
(
std
::
size_t
,
void
*
p
)
{
return
p
;
}