有效调整动态数组的大小

时间:2014-05-10 22:31:31

标签: c++ dynamic-arrays

我有一个动态数组作为我班级的成员。我正在尝试找到一种有效的方法来调整它并保留其中的所有信息。我知道矢量可以很好地用于此,但我想用动态数组来做这个。

我的班级有一个动态数组 unsigned _int8 ,称为数据。

以下是否可以接受?

unsigned _int8 * temp = data;
data = new unsigned _int8[NewSize]();

if(OldSize >= NewSize)
{
    for(int i = 0; i < NewSize; i++)
        data[i] = temp[i];
}
else
{
    for(int i = 0; i < OldSize; i++)
        data[i] = temp[i];
}

delete [] temp;

或者我应该采用不同的方式吗?有什么建议吗?

修改

修复了我的示例中的错误,并将char更改为unsigned _int8。

修改2

如果有的话,我不会经常重新分配。我希望功能在那里,以避免编写代码来创建一个新对象,并在需要时复制所有内容。

我写的课程是用于创建和保存位图(.bmp)图像。该数组只保存文件字节。当我创建对象时,(应该)知道图像大小。

3 个答案:

答案 0 :(得分:1)

由于数组使用POD (plain old data)类型,您可以使用memcpy()代替循环:

unsigned _int8 *temp = new unsigned _int8[NewSize];

if (OldSize >= NewSize)
    memcpy(temp, data, NewSize * sizeof(unsigned _int8));
else
{
    memcpy(temp, data, OldSize);
    memset(&temp[OldSize], 0, (NewSize-OldSize) * sizeof(unsigned _int8));
}

delete[] data;
data = temp;

或至少使用std::copy()(对于POD类型,std::copy()memcpy()类似,但对于非POD类型,它使用循环以保留对象分配语义):

unsigned _int8 *temp = new unsigned _int8[NewSize];

if (OldSize >= NewSize)
    std::copy(data, &data[NewSize], temp);
else
{
    std::copy(data, &data[OldSize], temp);
    std::memset(&temp[OldSize], 0, (NewSize-OldSize) * sizeof(unsigned _int8));
}

delete[] data;
data = temp;

话虽如此,你真的应该使用std::vector<unsigned _int8>代替。它为您处理这些细节。这种类型的数组管理是您必须在C中使用的,但如果您可以避免使用它,实际上不应该在C ++中使用,而是使用本机C ++功能。

答案 1 :(得分:0)

通过这种方式,每次将新元素添加到数组时,都必须调整其大小。 并且调整大小操作是Θ(n),因此插入操作也变为Θ(n)。

常见的过程是每次必须调整大小时复制(或复制等)数组大小,这样,调整大小操作仍然是Θ(n),但是摊销的插入成本是Θ(1)。

此外,通常容量与大小分开,因为容量是实现细节,而大小是数组接口的一部分。

你可能想要验证,当元素被移除时,容量是否太大,如果是,则减少它,否则,一旦它变大,该空间将永远不会释放。

您可以在此处查看更多相关信息: http://en.wikipedia.org/wiki/Dynamic_array

答案 2 :(得分:0)

这种方法的问题在于您只需调整大小即可。这意味着当您插入新元素时,执行此操作所需的时间会有很大差异。

因此,例如,如果您继续执行“push_back”操作,那么您将一直重新分配。

另一个想法是分配额外的大小以避免频繁的重新分配,这会导致性能成本很高

例如,

Vector可以分配额外的大小以使其具有一个缓和的redimensionning常量。

这是一个详细说明它的链接

stl中的vector使用此方法更有效率。

Amortized analysis of std::vector insertion