malloc分配的对象的动态类型是什么?

时间:2016-03-15 20:18:28

标签: c++ malloc language-lawyer

C ++标准指的是术语“动态类型”(C标准在类似的上下文中指的是“有效类型”),例如

  

如果某个程序试图通过以下某种类型之外的 glvalue 访问对象的存储值,则行为未定义:

     
      
  • 对象的动态类型,
  •   

但是如何确定用malloc分配的对象的动态类型?

例如:

void *p = malloc(sizeof(int));
int *pi = (int*)p;

pi指向的对象的动态类型是int吗?

5 个答案:

答案 0 :(得分:8)

根据C ++规范:

  

动态类型:

     

< glvalue>由glvalue表达式表示的glvalue引用的最派生对象(1.8)的类型

malloc的返回值是未初始化存储的块。在该存储中没有构造任何对象。因此它没有动态类型。

void*不指向对象,只有对象具有动态类型。

您可以通过开始其生命周期在该存储中创建对象。但是在你这样做之前,它只是存储。

答案 1 :(得分:4)

在C中,有效类型仅在您访问对象时相关。然后在

确定
  • 声明类型,如果有一个
  • 它是副本的另一个对象的类型(例如memcpy
  • 访问它的左值的类型,例如,void*被转换为另一种指针类型(例如int*),然后被解除引用。

后者通常是malloc ed对象发生的情况,如果将malloc的返回值赋给指针类型。

答案 2 :(得分:3)

动态类型是描述基本上多态对象的正式术语,即具有至少一个virtual函数的对象。因此,它是一个C ++术语,因为C没有virtual的概念,例如。

  

但是如何使用malloc分配对象的动态类型   来确定

不是。 malloc分配N 原始字节的内存并通过void*返回 - 这是推断正确类型的工作。此外,此内存仅表示放置对象的区域,但在显式调用其构造函数之前,此对象将不会处于活动状态。 (再次,从C ++的角度来看)

  

pi指向的对象的动态类型是否为int?

不,因为在描述具有类类型的对象时,术语动态类型是有意义的。 int不是也不是。

class Foo
{
   //virtual ~Foo() = default; 
   virtual void f() {}
};

class Bar : public Foo
{
  virtual void f() {}
};

// ...
Foo *ptr = new Bar();

此处Fooptr的静态类型,而Bar是其动态类型。

答案 3 :(得分:3)

现状是malloc不会创建对象。唯一的构造是new表达式,定义,强制转换和赋值给变体成员。请参阅P0137R0以获取正确的措辞。

如果您想使用malloc产生的存储空间,假设它已正确对齐(除非您使用扩展路线,情况就是这种情况),请调用新的位置:

auto p = malloc(sizeof(int));
int* i = new (p) int{0};
// i points to an object of type int, initialized to zero

因此,在C ++中使用malloc是没有用的,因为沼泽标准new有效地将上述步骤合并为一个。

请参阅提问者相关问题中的@T.C.'s answer

答案 4 :(得分:0)

根据C ++ 11标准中的1.3.7,

  

动态类型   由glvalue表达式表示的glvalue指向的最派生对象(1.8)的 glvalue 类型   [例如:如果指针(8.3.1)p的静态类型是“指向B类的指针”,则指向类的对象   D,源自B(第10条),表达式* p的动态类型是“D”。参考文献(8.3.2)被处理   与此类似。 - 结束例子]

示例

install_name_tool

class A {} class B : public A {} A *a = new B; 的“静态”类型为a,而其动态类型为A *

引用不同类型的想法来防止像

这样的事情
B *

可能导致未定义的行为。

class A{} class B : public A {int x;} class C : public A {int y;} A *a = new B; reinterpret_cast<C *>(a)->x; 没有指向一个对象,但动态和声明类型之间的区别仅对对象有意义。