Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么运算符new[]为数组大小分配内存?_C++_Dynamic Memory Allocation - Fatal编程技术网

C++ 为什么运算符new[]为数组大小分配内存?

C++ 为什么运算符new[]为数组大小分配内存?,c++,dynamic-memory-allocation,C++,Dynamic Memory Allocation,我实现了一个堆栈分配器,并为某个类重载了操作符new[],以使用我自己的分配器。然后我注意到操作符new[]为分配的数组中的元素数量分配了内存。 例如: test_class*test_arr=新的测试类[5] 从我的分配器请求8个字节+5*sizeof(test_类),并在前8个字节中存储数组的大小,在本例中为5 为什么会这样?我的分配器的工作是跟踪分配的内存量。对于那部分来说,这真的没有意义,是吗?那有什么意义呢? 另外,我是否可以(或不应该?)以某种方式“关闭它”?很可能newt[N]将请

我实现了一个堆栈分配器,并为某个类重载了
操作符new[]
,以使用我自己的分配器。然后我注意到
操作符new[]
为分配的数组中的元素数量分配了内存。
例如:

test_class*test_arr=新的测试类[5]

从我的分配器请求8个字节+5*sizeof(test_类),并在前8个字节中存储数组的大小,在本例中为5

为什么会这样?我的分配器的工作是跟踪分配的内存量。对于那部分来说,这真的没有意义,是吗?那有什么意义呢?
另外,我是否可以(或不应该?)以某种方式“关闭它”?

很可能
newt[N]
将请求一个指针
p
指向大小为
sizeof(size_t)+N*sizeof(t)
字节的内存,将N存储在第一个
sizeof(size_t)
字节中,然后将
(t*)((size_t*)p)+1)返回给用户(因此第一个
T
位于返回的指针处。)


然后
delete[]
将使用给定的指针,查看
*(p-sizeof(size\t))
以查看要销毁的对象数量,销毁它们,并将
((size\t*)p)-1
传递给要释放的底层分配器。

当您在代码中写入
p=new t[N]
时,编译器生成调用
运算符new[]
T
类型的
N
对象以及它需要的任何簿记信息分配足够的内存。当您随后调用
delete[]p
时,编译器为
p
指向的数组中的每个
N
元素调用析构函数,然后调用
操作符delete[]
释放从
operator new[]获取的内存。

但是
N
并不总是具有相同的值。您可以执行
p=new t[3];delete[]p;p=new t[4];delete[]p;
,这两次删除将分别运行不同数量的析构函数

为了调用正确数量的析构函数,必须在某个地方有一个注释,记录
p
指向的数组中有多少个对象。该注释通常存储在编译器通过调用
操作符new[]
获得的内存的簿记部分。这就是为什么它需要额外的空间

这是当今的典型实现,但编译器不需要这样做。例如,至少有一个早期实现保留了指针值和析构函数计数的单独表


此外,许多实现不会对没有析构函数的类型使用额外的开销。因此
int*p=new int[3]
只需调用
operator new(3*sizeof(int)
,而
delete[]p
只需调用
operator delete(p)

分配器通过存储大小和分配的内存来跟踪分配的内存。查看
操作员删除[]的代码
@MustafaOzturk In libstdc++
delete
只将
void*
传递给
std::free
。因此在我的示例中,它将传递指向第一个
test\u类
元素的指针。
free
不知道指针的类型,那么为什么数组中的元素数量会带来好处呢?我不是专家但是,如果你的类有一个不重要的析构函数,DEL[]需要知道它在C++上的调用元素有多少个[D][/C]>不<代码>删除< /C>。
存储数组中对象的数量,以便
操作符delete[]
知道必须销毁多少对象。似乎是这样,但这是标准指定的吗?同时
void*
会传递给
delete[]
,delete如何知道调用哪个类析构函数?@MikevanDyke:当析构函数传递到
delete[]时,它已经被调用了。
。小心伪指针算法:
*(p-sizeof(size\t))
没有意义,除非
p
具有类型
char*
。对于任何其他指针类型
p-sizeof(size\t)
指向杂草,并且行为未定义。您可以执行
(size\t*)p-1
而不是。@jxh——也许吧。我的观点更多的是建议讨论它是如何工作的,而不是试图拼凑一段代码片段,它可能会或可能不会显示实际发生了什么。