为什么我不能将 `new [ ]` 与 smart_pointers 一起使用?
Why can not I use `new [ ]` with smart_pointers?
为什么我不能将 new [ ]
与 smart_pointers 一起使用?
其实这段文字我看不懂
Caution You should use an auto_prt or shared_ptr object only for
memory allocated by new, not for memory allocated by new []. You
should not use auto_ptr, shared_ptr,orunique_ptr for memory not
allocated via new or, in the case of unique_ptr, via new or new[].
示例:
#include <memory>
int
main()
{
auto p1 = std::unique_ptr<char[]>{new char[3]}; // C++11
auto p2 = std::shared_ptr<char>{new char[3], [](char* p) {delete [] p;}}; // C++11
auto p3 = std::make_unique<char[]>(3); // C++14
}
第一个和第二个适用于 C++11 及更高版本。第三个是在 C++14 中引入的。第一个和第三个代表新的唯一所有权,第二个代表新的共享所有权。
Why can not I use new[]
with smart pointers?
通常可以,但智能指针必须知道它存储的是一个动态分配的数组,而不是单个对象。这是因为使用运算符 new[]
分配的对象应该使用运算符 delete[]
、 而不是 delete
释放。智能指针如何知道应该应用哪个运算符?
通过为数组类型提供智能指针 class 模板的专门化来区分,就像目前在 std::unique_ptr<T>
:
中所做的那样
std::unique_ptr<int> ptr(new int); // will call delete
std::unique_ptr<int[]> arr(new int[5]); // will call delete[]
↑↑
但是,该语法(尚未)适用于标准库中可用的所有智能指针类型。
为了进行比较,Boost Smart Pointers 库提供了单独的 class 模板,用于存储指向动态分配数组的指针:
boost::shared_array<int> arr1(new int[5]); // will call delete[]
// ~~~~^
boost::scoped_array<int> arr2(new int[5]); // will call delete[]
// ~~~~^
You should use an auto_ptr
or shared_ptr
object only for memory allocated by new
, not for memory allocated by new []
.
std::auto_ptr<T>
(† 2017)1 将普通 delete
运算符应用于它存储的指针,并且无法更改该行为。因此,存储指向数组的指针不是一种选择。
据std::shared_ptr<T>
is concerned, by default it does the same (calls operator delete
). To change that behavior, and properly deallocate a memory area of a stored array, you could use a custom deleter, like std::default_delete<T[]>
:
std::shared_ptr<int> arr(new int[5], std::default_delete<int[]>{});
↑↑
或自己提供的其他一些:
std::shared_ptr<int> arr(new int[5], [](int* ptr) { delete[] ptr; } );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
但是,缺少 std::shared_ptr<T[]>
的特化意味着没有 operator[]
可以让您轻松访问存储数组的元素,这会导致不直观的语法,例如 arr.get()[0]
.
随着提议 N4077 的引入,将 数组类型指针的特化:
std::shared_ptr<int[]> arr(new int[5]); // will call delete[]
↑↑
You should not use auto_ptr
, shared_ptr
, or unique_ptr
for memory not allocated via new
or, in the case of unique_ptr
, via new
or new[]
.
这段摘录简单地指出,不应从指向未动态分配的对象的指针构造智能指针,因为(默认情况下)它会导致对未分配的对象调用 delete
使用 new
(同上 new[]
/delete[]
)。
What is the difference between unique_ptr<double[]> p1(new double[2]);
, unique_ptr<double> p2(new double[2]);
, unique_ptr<double[]> p3(new double(2));
?
std::unique_ptr<double[]> p1(new double[2]);
OK:从指向两个 double
秒。它将调用 delete[]
来释放指向的内存。
std::unique_ptr<double> p2(new double[2]);
错误:从指向两个 double
秒。它将调用 delete
(!) 来释放指向的内存。 (可能是未定义的行为 - new[]
和 delete
之间的不匹配)。
std::unique_ptr<double[]> p3(new double(2));
错误:从指向 single [=48= 的指针(并取得所有权)构造 unique_ptr
] 初始化为值 2
。它将调用 delete[]
(!) 来释放指向的内存。 (可能是未定义的行为 - new
和 delete[]
之间的不匹配)。
1 std::auto_ptr<T>
自 C++11 起被弃用,取而代之的是 std::unique_ptr<T>
,并将从 C++ 的标准库中删除1z 根据 N4168.
为什么我不能将 new [ ]
与 smart_pointers 一起使用?
其实这段文字我看不懂
Caution You should use an auto_prt or shared_ptr object only for memory allocated by new, not for memory allocated by new []. You should not use auto_ptr, shared_ptr,orunique_ptr for memory not allocated via new or, in the case of unique_ptr, via new or new[].
示例:
#include <memory>
int
main()
{
auto p1 = std::unique_ptr<char[]>{new char[3]}; // C++11
auto p2 = std::shared_ptr<char>{new char[3], [](char* p) {delete [] p;}}; // C++11
auto p3 = std::make_unique<char[]>(3); // C++14
}
第一个和第二个适用于 C++11 及更高版本。第三个是在 C++14 中引入的。第一个和第三个代表新的唯一所有权,第二个代表新的共享所有权。
Why can not I use
new[]
with smart pointers?
通常可以,但智能指针必须知道它存储的是一个动态分配的数组,而不是单个对象。这是因为使用运算符 new[]
分配的对象应该使用运算符 delete[]
、 而不是 delete
释放。智能指针如何知道应该应用哪个运算符?
通过为数组类型提供智能指针 class 模板的专门化来区分,就像目前在 std::unique_ptr<T>
:
std::unique_ptr<int> ptr(new int); // will call delete
std::unique_ptr<int[]> arr(new int[5]); // will call delete[]
↑↑
但是,该语法(尚未)适用于标准库中可用的所有智能指针类型。
为了进行比较,Boost Smart Pointers 库提供了单独的 class 模板,用于存储指向动态分配数组的指针:
boost::shared_array<int> arr1(new int[5]); // will call delete[]
// ~~~~^
boost::scoped_array<int> arr2(new int[5]); // will call delete[]
// ~~~~^
You should use an
auto_ptr
orshared_ptr
object only for memory allocated bynew
, not for memory allocated bynew []
.
std::auto_ptr<T>
(† 2017)1 将普通 delete
运算符应用于它存储的指针,并且无法更改该行为。因此,存储指向数组的指针不是一种选择。
据std::shared_ptr<T>
is concerned, by default it does the same (calls operator delete
). To change that behavior, and properly deallocate a memory area of a stored array, you could use a custom deleter, like std::default_delete<T[]>
:
std::shared_ptr<int> arr(new int[5], std::default_delete<int[]>{});
↑↑
或自己提供的其他一些:
std::shared_ptr<int> arr(new int[5], [](int* ptr) { delete[] ptr; } );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
但是,缺少 std::shared_ptr<T[]>
的特化意味着没有 operator[]
可以让您轻松访问存储数组的元素,这会导致不直观的语法,例如 arr.get()[0]
.
随着提议 N4077 的引入,将 数组类型指针的特化:
std::shared_ptr<int[]> arr(new int[5]); // will call delete[]
↑↑
You should not use
auto_ptr
,shared_ptr
, orunique_ptr
for memory not allocated vianew
or, in the case ofunique_ptr
, vianew
ornew[]
.
这段摘录简单地指出,不应从指向未动态分配的对象的指针构造智能指针,因为(默认情况下)它会导致对未分配的对象调用 delete
使用 new
(同上 new[]
/delete[]
)。
What is the difference between
unique_ptr<double[]> p1(new double[2]);
,unique_ptr<double> p2(new double[2]);
,unique_ptr<double[]> p3(new double(2));
?
std::unique_ptr<double[]> p1(new double[2]);
OK:从指向两个 double
秒。它将调用 delete[]
来释放指向的内存。
std::unique_ptr<double> p2(new double[2]);
错误:从指向两个 double
秒。它将调用 delete
(!) 来释放指向的内存。 (可能是未定义的行为 - new[]
和 delete
之间的不匹配)。
std::unique_ptr<double[]> p3(new double(2));
错误:从指向 single [=48= 的指针(并取得所有权)构造 unique_ptr
] 初始化为值 2
。它将调用 delete[]
(!) 来释放指向的内存。 (可能是未定义的行为 - new
和 delete[]
之间的不匹配)。
1 std::auto_ptr<T>
自 C++11 起被弃用,取而代之的是 std::unique_ptr<T>
,并将从 C++ 的标准库中删除1z 根据 N4168.