std :: realloc与static_cast或放置新

时间:2018-07-14 23:55:13

标签: c++

根据reinterpret_cast creating a trivially default-constructible object个具有琐碎默认构造函数的对象,无法通过简单地重新解释适当对齐的存储来创建[]。这应同样适用于std::realloc。是cppreference example中的static_cast

#include <cstdlib>
class MallocDynamicBuffer
{
    char* p;
public:
    void resize(std::size_t newSize) {
        if(void* mem = std::realloc(p, newSize)) {
            p = static_cast<char*>(mem);
        }
    }
};

不正确,因为它没有创建有效的对象?

将包含static_cast的行替换为p = new(mem) T[newSize],替换为T=char或任何其他可轻松复制和可轻松构造的类型是否正确?我不确定,因为这将要求对先前构建和移动的数据调用new放置是有效的。并且,调用一个平凡可构造类型的构造函数可以保证该值保持不变而不是不确定。

1 个答案:

答案 0 :(得分:1)

实用答案:如果trivially copyable types不允许使用realloc(也就是说,所有复制和移动构造函数和赋值运算符都是微不足道的,则至少有一个复制或移动构造函数或赋值运算符,并且析构函数是微不足道的),这似乎是标准中的错误,我无法想象编译器编写器会在此处引起问题。

语言律师回答:除charunsigned charstd::byte以外的其他任何类型的标准都不允许这样做,我不再确定关于我评论该问题时的情况(如果有realloc创建的一些基础对象,那没有关系)。这些函数are specified用于“具有C标准库中指定的语义”,这并不是特别有用,因为C不具有与C ++“对象”概念等效的语义。对malloc的一般理解是,它不会创建C ++对象,因此您需要自己通过放置new来完成;我假设realloc也会发生同样的情况。

您在new[]的结果上使用位置realloc的建议解决方案也不起作用。由于new[]需要跟踪分配的元素数量(供delete[]使用),因此it is allowed要添加一些开销空间,然后在其收到的指针之后返回一个指针,因此第一部分是开销。尽管对于展示位置new[]it is still allowed并不是必须的(这使我认为根本没有有效的方法来使用展示位置new[],因为您不知道会有多少开销要求,因此不能确保您有足够的空间。

即使您确定只使用了非数组放置new(我可以想到在realloc仍然可行的几个解决方法中),它的确会在其中创建有效的对象(对于具有trivial default constructors,默认初始化时至少不允许执行此操作),但它可能具有indeterminate value。现在,在我看来,它可能有效,但标准有些含糊,但是that is debatable和我可能是错的。