新分配了多少字节?

时间:2012-09-21 05:40:07

标签: c++ linux memory-management

  

可能重复:
  How to get memory block length after malloc?

如果我有一个指针,是否可以了解new分配了多少字节? 当我用Google搜索时,我找到了适用于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分配的所有内存。 这意味着它可以以某种方式计算只知道指针。那么将它从程序员中隐藏起来的原因是什么?

6 个答案:

答案 0 :(得分:5)

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

  • 在某些平台上,deletefree根本不执行任何操作。因此,他们不需要存储大小信息。这在嵌入式平台中非常常见;它允许你使用为其他平台编写的C或C ++代码不变,只要你不做太多的分配。
  • 即使在更常见的平台上,系统也可能分配不同于您要求的字节数。通常,您的分配将与某个较大的大小对齐 - 可能大于原始请求。存储元数据也可能存储在一个非常慢的数据结构中 - 您不希望在时间关键代码中获取锁并访问哈希表。

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

答案 1 :(得分:3)

newmalloccalloc以及该语言中所有其他与堆相关的分配(是的,除此之外还有很多)将分配至少您请求的内存量。他们可能分配更多(一般他们会分配更多)。

没有便携的方法可以知道他们分配了多少。事实上,除非您确切知道正在使用的堆管理器,否则根本没有办法。

你还需要区分你可以安全访问的内存意义上的已分配内存与返回的指针(这是malloc_size在mac上返回的内容以及可能是_msize在windows上返回的内容)与从堆中取出的实际内存'因为分配(包括可能会或可能不会与您分配的内存块相邻的簿记信息,对于相同大小的分配可能相同或不同)。

答案 2 :(得分:1)

问:那么我可以查询malloc包以找出分配的块有多大吗?

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

C-FAQ

答案 3 :(得分:1)

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

E.g。

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

将分配sizeof(int) * 100但您无法知道如果A的实施对您隐藏。

如果你表现自己:

int * x = new int [100];

然后您知道您分配了多少,因为有权访问sizeof(primitive)

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

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

答案 4 :(得分:1)

除了上面的答案之外:在某些情况下,必须分配和解除分配的大小在编译时是已知的,并且它将是完整的内存腰,以记录某处的大小。

如果静态类型等于动态类型,则要取消分配的内存可以由类型确定。

如果静态类型不等于动态类型,则删除的对象类必须具有虚拟析构函数。这个析构函数可用于释放正确大小的内存。

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

答案 5 :(得分:0)

 X x=new X()

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

int x = new int [100];

这取决于要分配多少元素 .suppose,int需要2个字节,然后这需要200个字节。
很快,我们可以说,它取决于数据类型,使用新的运算符