【发布时间】:2018-10-22 06:00:12
【问题描述】:
我正在编写一个动态数组供我自己使用,我想用零预设。
template <class T>
dynArr<T>::dynArr()
{
rawData = malloc(sizeof(T) * 20); //we allocate space for 20 elems
memset(this->rawData, 0, sizeof(T) * 20); //we zero it!
currentSize = 20;
dataPtr = static_cast<T*>(rawData); //we cast pointer to required datatype.
}
这部分有效 - 使用 dereferencind 循环迭代 dataPtr 效果很好。零。
然而,重新分配的行为(在我看来)至少有点奇怪。首先你要看看重新分配代码:
template <class T>
void dynArr<T>::insert(const int index, const T& data)
{
if (index < currentSize - 1)
{
dataPtr[index] = data; //we can just insert things, array is zero-d
}
else
{
//TODO we should increase size exponentially, not just to the element we want
const size_t lastSize = currentSize; //store current size (before realloc). this is count not bytes.
rawData = realloc(rawData, index + 1); //rawData points now to new location in the memory
dataPtr = (T*)rawData;
memset(dataPtr + lastSize - 1, 0, sizeof(T) * index - lastSize - 1); //we zero from ptr+last size to index
dataPtr[index] = data;
currentSize = index + 1;
}
}
很简单,我们将数据重新分配到 index+1,并将尚未归零的内存设置为 0。
作为一个测试,我首先在这个数组的第 5 位插入了 5。预期的事情发生了 - 0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
然而,插入其他东西,比如 insert(30,30) 会给我带来奇怪的行为:
0, 0, 0, 0, 0, 5, 0, -50331648, 16645629, 0, 523809160, 57600, 50928864, 50922840, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
什么鬼,我这里有什么不明白的吗? realloc 不应该考虑所有 20 个先前设置的内存字节吗?这是什么魔法。
【问题讨论】:
-
你忘了在 realloc 调用中将
(index+1)与sizeof(T)相乘。 -
rawData = realloc(rawData, index + 1);如果失败,您将丢失所有数据。 -
另外,原始内存
malloc和realloc返回不包含对象,您必须在使用placement new 分配之前创建它们。否则,您将调用未定义的行为。 -
dataPtr[index] = data;是 wooong.. 这不是 C...