1

我终于决定好好学习C++,我在一本增加数组大小的书中遇到了下面的代码。该函数接受一个指向具有其原始大小的数组的指针,并返回一个大小为两倍的新数组。

int *doubleArraySize(int *p_array, int *p_size) {
    *p_size *= 2;

    int *p_new_array = new int[*p_size];
    for(int i = 0; i < *p_size; i++)
        p_new_array[i] = p_array[i];

    delete[] p_array;
    return p_new_array;
}

当我们到达 for 循环时,值*p_size已经翻了一番。这意味着(至少对我而言)当我们访问时,p_array[i]我们最终会进入不属于的内存区域p_array。这是一个问题吗?这段代码会崩溃吗?如果没有,我错过了什么?

4

3 回答 3

10

那不是安全代码。您从超出其限制的范围内复制p_array(如果它是以前的*p_size)。虽然它可能不会崩溃,但它仍然是未定义的行为

我有两个建议:

  1. 使用std::vector
  2. 如果没有,那么至少std::copy_n用于复制(当然大小正确)。
于 2013-06-08T20:48:55.903 回答
4

您最大的问题是您*p_size过早地乘以 2,因此您在for循环中读取了旧数组的末尾。

您可以通过将乘法推迟到复制之后来解决此问题:

int extend_arr(int *old, size_t *sz)
{
    int *newarr = new int[*sz * 2];
    for (size_t i = 0; i < *sz; i++)
        newarr[i] = old[i];

    *sz *= 2;
    return newarr;
}

一个常见的警告:你为什么不使用std::vector呢?使用矢量,您可以只使用resize()它并让标准库完成艰苦的工作。

于 2013-06-08T20:49:17.490 回答
0

new可能会失败并引发异常。

还存在指针可能为 NULL 的风险。

于 2013-06-08T20:43:38.160 回答