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



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

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

  • 对象的动态类型,

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

例如:

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

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

根据C++规范:

动态类型:

派生最多的对象 (1.8) 的类型,glvalue 表达式表示的 glvalue 所指的类型

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

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

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

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

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

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

动态类型是一个正式术语,用于描述本质上的多态对象,即具有至少一个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是其动态类型。

现状是malloc不创建对象。唯一这样做的构造是new表达式、定义、强制转换和变量成员赋值。有关此内容的正确措辞,请参阅P0137R0。

如果要使用由 malloc 生成的存储,假设它已正确对齐(除非使用扩展对齐,否则情况如此),请调用放置 new:

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.在提问者相关问题中的回答。

根据 C++11 标准中的 1.3.7

动态类型 最派生对象的 glvalue 类型 (1.8),GLvalue 表达式表示的 GLVALUE 所指的 GLVALUE 类型 [示例:如果静态类型为"指向类 B"的指针 (8.3.1) p 指向类的对象 D,派生自 B(条款 10),表达式 *p 的动态类型为"D"。处理引用 (8.3.2) 同样地。— 结束示例 ]

举个例子

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;

这可能会导致未定义的行为。

void *不指向对象,但动态类型和声明类型之间的区别仅对对象有意义。

相关内容

  • 没有找到相关文章

最新更新