提问者:小点点

在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;

还是未定义的行为吗?


共2个答案

匿名用户

真的吗?

是的。 从技术上讲,没有任何一部分:

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

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

我们真的必须调用默认构造函数来启动对象的生命时间吗?

你必须按照C++对象模型来避免C++20之前的未定义行为吗? 是的。 任何编译器实际上会因为你不这样做而造成伤害吗? 据我所知没有。

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

是的。 在C++20之前,实际上还没有在任何地方创建int对象,因此这就是UB。

匿名用户

是的,是UB。 枚举了int可以存在的方式列表,没有一种方式适用于此,除非您认为malloc是aausal的。

它被广泛认为是标准中的一个缺陷,但重要性不高,因为C++编译器围绕UB的特定部分所做的优化并没有引起用例的问题。

至于第二个问题,C++并没有强制要求C++和C如何交互。 所以所有与C的交互都是。。。UB,也就是C++标准没有定义的行为。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++20|malloc|int|未定义)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?