new分配了多少字节

How many bytes were allocated by new?

本文关键字:字节 多少 分配 new      更新时间:2023-10-16

可能的重复:
如何获取malloc之后的内存块长度?

如果我有一个指针,是否可以了解new分配了多少字节?当我在谷歌上搜索时,我找到了一个适用于Windows:_msize()和Mac:malloc_size()的解决方案。但对Linux来说什么都不是。

如果没有,有人知道为什么它对程序员隐藏吗?delete肯定知道这些信息。

更新:

据我所知,如果我有这个代码:

class A {   
~A() {}
int m_a; 
}; 
class B : public A {
~B() {}
int m_b; 
};
int main() {   A * b = new B();   delete b;   return 0; }

A的析构函数将被调用,但new分配的所有内存仍将被释放。这意味着它可以在只知道指针的情况下以某种方式进行计算。那么,对程序员隐瞒它的原因是什么呢?

不幸的是,没有可移植的方法来获取newmalloc分配的字节数。出现这种情况的原因有很多:

  • 在某些平台上,deletefree什么都不做。因此,它们不需要存储大小信息。这在嵌入式平台中非常常见;它允许您使用为其他平台编写的C或C++代码,只要您不做太多分配,就可以保持不变
  • 即使在更常见的平台上,系统分配的字节数也可能与您要求的不同。通常情况下,您的分配将与更大的大小对齐,可能比您的原始请求大得多。存储元数据也可能存储在一个非常慢的数据结构中——您不希望在时间关键型代码中获取锁和访问哈希表

作为可移植语言,C和C++不能提供在每个平台上都不可用(或定义良好或相当快)的功能。这就是为什么这在C++上不可用。也就是说,你不需要这个-C++提供std::vector可以跟踪你的分配大小,或者std::string为你处理所有这些细节。

newmalloccalloc和该语言中所有其他与堆相关的分配(是的,还有很多)将至少分配您请求的内存量。他们可能分配更多(通常他们会分配更多)。

没有可移植的方法来知道他们分配了多少。事实上,除非您确切地知道您使用的是什么堆管理器,否则根本没有办法。

您还需要从可以安全访问的内存的意义上区分已分配的内存与返回的指针(这是malloc_size在Mac上返回的,可能是_msize在windows上返回的)以及由于分配而"从堆中拿走"的实际内存(其中包括与您分配的内存块相邻或不相邻的记账信息,对于相同大小的分配,记账信息可能相同或不相同)。

Q:那么我可以查询malloc包来了解分配的块有多大吗?

A: 不幸的是,没有标准的或可移植的方法。(有些编译器提供非标准扩展。)如果你需要知道,你必须自己跟踪它。

C-FAQ

new运算符所做的是调用构造函数,因此分配的大小取决于您调用的构造函数的类型。

例如

class A
{
private:
int* x;
public:
A() { x = new int [100]; }
};

将分配sizeof(int) * 100,但您无法知道A的实现是否对您隐藏。

如果你自己表演:

int * x = new int [100];

然后你就知道你已经分配了多少,因为你可以访问sizeof(primitive)

此外,delete运算符调用析构函数,因此对于复杂对象,它再次不需要知道所分配内存的大小,因为完全正确释放内存的责任完全委托给了程序员。

所以这里没有一个直接的答案。

除了上面的答案之外:在某些情况下,必须分配和释放的大小在编译时是已知的,记录大小将是一个完整的内存。

在静态类型等于动态类型的情况下,可以通过类型来确定要释放的内存。

在静态类型不等于动态类型的情况下,已删除对象类必须具有虚拟析构函数。此析构函数可用于释放适当大小的内存。

在分配数组时,数组的大小通常以依赖于实现的方式附加到该数组,并且要释放的大小可以由元素的类型和数组的大小来确定。

X x=new X()

这里它取决于类的大小,即类包含的变量数。

int x = new int [100];

这里它取决于你要分配多少元素。假设int需要2个字节,那么这里需要200个字节
很快,我们可以说,它取决于数据类型,对此,您使用新的运算符