我接手了一些代码,发现一个奇怪的数组重新分配。这是一个在Array类中使用的函数(被JsonValue使用)。
void reserve( uint32_t newCapacity ) {
if ( newCapacity > length + additionalCapacity ) {
newCapacity = std::min( newCapacity, length + std::numeric_limits<decltype( additionalCapacity )>::max() );
JsonValue *newPtr = new JsonValue[newCapacity];
if ( length > 0 ) {
memcpy( newPtr, values, length * sizeof( JsonValue ) );
memset( values, 0, length * sizeof( JsonValue ) );
}
delete[] values;
values = newPtr;
additionalCapacity = uint16_t( newCapacity - length );
}
}
我明白了,这只是为了分配一个新数组,并将旧数组的内存内容复制到新数组中,然后将旧数组的内容清零。我知道这是为了防止调用析构函数和移动操作而执行的。
JsonValue是一个带有函数和一些数据的类,这些数据存储在联合体中(例如字符串、数组、数字等)。
我的担忧是这是否属于已定义的行为。我知道它能够正常工作,并且在我们几个月前开始使用以来没有出现过问题;但是如果它是未定义的,那么它并不意味着它会持续工作。
编辑:
JsonValue
看起来像这样:struct JsonValue {
// …
~JsonValue() {
switch ( details.type ) {
case Type::Array:
case Type::Object:
array.destroy();
break;
case Type::String:
delete[] string.buffer;
break;
default: break;
}
}
private:
struct Details {
Key key = Key::Unknown;
Type type = Type::Null; // (0)
};
union {
Array array;
String string;
EmbedString embedString;
Number number;
Details details;
};
};
Array
是围绕着一个 JsonValue
数组的包装器,String
是一个 char*
,EmbedString
是一个 char[14]
,Number
是一个由 int
、unsigned int
和 double
构成的联合体,Details
包含了它所持有的值的类型。所有的值在开头都有 16 位未使用的数据,用于存储 Details
。例如:
struct EmbedString {
uint16_t : 16;
char buffer[14] = { 0 };
};
values
是从哪里来的?它是实例变量还是全局变量? - SimonCreserve
函数是类的一部分。 - ChrisMM