在C ++ 20之前将malloc用于int未定义行为

问题描述

有人告诉我,以下代码在C ++ 20之前具有未定义的行为:

int *p = (int*)malloc(sizeof(int));
*p = 10;

是真的吗?

该论据是int对象的生存期在为其分配值(P0593R6)之前没有开始。要解决此问题,应使用放置new

int *p = (int*)malloc(sizeof(int));
new (p) int;
*p = 10;

我们真的必须调用一个琐碎的默认构造函数来启动对象的生存期吗?

同时,该代码在纯C语言中没有未定义的行为。但是,如果我在C代码中分配一个int并在C ++代码中使用它会怎样?

// C source code:
int *alloc_int(void)
{
    int *p = (int*)malloc(sizeof(int));
    *p = 10;
    return p;
}

// C++ source code:
extern "C" int *alloc_int(void);

auto p = alloc_int();
*p = 20;

它仍然是未定义的行为吗?

解决方法

是真的吗?

是的。从技术上讲,不包含以下内容:

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

实际上创建了一个int类型的对象,因此取消引用p是UB,因为那里没有实际的int

我们真的必须调用琐碎的默认构造函数来启动对象的生命周期吗?

您是否必须按照C ++对象模型来避免C ++ 20之前的未定义行为?是。如果不这样做,编译器实际上会造成伤害吗?并不是我所知道的。

[...]仍然是未定义的行为吗?

是的。在C ++ 20之前的版本中,您实际上仍未在任何地方创建int对象,因此它是UB。

,

是的,是UB。列举了int的存在方式列表,但没有一个适用的方法,除非您认为malloc是因果关系的。

它被广泛认为是标准中的缺陷,但重要性不高,因为C ++编译器针对特定的UB进行的优化不会导致该用例出现问题。

对于第二个问题,C ++并不要求C ++和C如何交互。因此,所有与C的交互都是... UB,也就是C ++标准未定义的行为。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...