当我执行 new T[1] 时发生了什么?
What's happening when I do new T[1]?
在这里快速提问:
template <class T>
T* allocate(std::size_t n){
return new T[n];
}
所以在上面的代码中,当n==1
时,我们在做new T[1]
,所以我有两个担心:
1.I 听说在分配数组时,额外的内存用于存储数组的长度(虽然不确定),所以如果 new T[1]
很多,这会不会是恶意的,浪费很多内存?
2.Should 我使用 delete[]
或简单地 delete
?
释放它
内存很便宜。确实,如果您的所有程序一直都在一遍又一遍地分配 1 个对象的数组,那么这会有点浪费,这是真的。但是偶尔分配 1 个元素的数组不会是世界末日。
使用delete[]
。如果您使用 new[]
,那么您必须使用 delete[]
。 new
编辑了多少并不重要。这是一个相当简单的规则。没有例外。
- 没有内存用于存储数组的长度,或者至少没有允许您访问的内存。授予您内存的内存管理器可能有一些隐藏的簿记。如果你找到这个簿记,别管它。你用它做的任何事情肯定是不可移植的。也可能会以固定大小的块为您提供内存。您将获得一个大小至少为
T
的块。此块中的任何额外内存实际上都被浪费了。
- 任何用
new[]
分配的东西都必须用 delete[]
释放,否则你会调用未定义的行为。再次强调,不要乱动底层内存管理器。
是的,在使用 new T[n]
的典型实现中,需要一些额外的内存来存储数组的确切长度,但 仅适用于非-平凡的析构函数。
例如在典型的实现中,new int[1]
与 new int
相比没有内存开销,但是 new std::string[1]
与 new std::string
相比会带来内存开销。
额外内存只是一个额外的 size_t
字段,这意味着百分比取决于您分配的对象的大小。如果 sizeof(T)
与 sizeof(size_t)
相当,开销可能相当大。
但这一切可能还取决于特定于实现的内存分配机制的其他细节。
换句话说,如果这是特定于应用程序的代码的一部分,那么尝试它并查看它是否对您的程序的内存消耗有任何负面影响是有意义的。也许这根本不是问题。但是如果你正在编写一个泛型库,那么类似的事情就值得关注了。
是的,你应该使用delete []
。
在这里快速提问:
template <class T>
T* allocate(std::size_t n){
return new T[n];
}
所以在上面的代码中,当n==1
时,我们在做new T[1]
,所以我有两个担心:
1.I 听说在分配数组时,额外的内存用于存储数组的长度(虽然不确定),所以如果 new T[1]
很多,这会不会是恶意的,浪费很多内存?
2.Should 我使用 delete[]
或简单地 delete
?
内存很便宜。确实,如果您的所有程序一直都在一遍又一遍地分配 1 个对象的数组,那么这会有点浪费,这是真的。但是偶尔分配 1 个元素的数组不会是世界末日。
使用
delete[]
。如果您使用new[]
,那么您必须使用delete[]
。new
编辑了多少并不重要。这是一个相当简单的规则。没有例外。
- 没有内存用于存储数组的长度,或者至少没有允许您访问的内存。授予您内存的内存管理器可能有一些隐藏的簿记。如果你找到这个簿记,别管它。你用它做的任何事情肯定是不可移植的。也可能会以固定大小的块为您提供内存。您将获得一个大小至少为
T
的块。此块中的任何额外内存实际上都被浪费了。 - 任何用
new[]
分配的东西都必须用delete[]
释放,否则你会调用未定义的行为。再次强调,不要乱动底层内存管理器。
是的,在使用
new T[n]
的典型实现中,需要一些额外的内存来存储数组的确切长度,但 仅适用于非-平凡的析构函数。例如在典型的实现中,
new int[1]
与new int
相比没有内存开销,但是new std::string[1]
与new std::string
相比会带来内存开销。额外内存只是一个额外的
size_t
字段,这意味着百分比取决于您分配的对象的大小。如果sizeof(T)
与sizeof(size_t)
相当,开销可能相当大。但这一切可能还取决于特定于实现的内存分配机制的其他细节。
换句话说,如果这是特定于应用程序的代码的一部分,那么尝试它并查看它是否对您的程序的内存消耗有任何负面影响是有意义的。也许这根本不是问题。但是如果你正在编写一个泛型库,那么类似的事情就值得关注了。
是的,你应该使用
delete []
。