分配指针数组时不使用“new”

Allocate pointer array without using `new`?

本文关键字:new 指针 数组 分配      更新时间:2023-10-16

这是我的代码:

int *arr1 = new int[size]();
int *arr2 = new int[size]();
int *arr3 = new int[size]();

我知道,我知道:如果我需要使用指针,我应该使用std::unique_ptr,但赋值要求我使用*数组(使用"动态分配"-我会使用std::vector,但出于某种原因,这也是不允许的)。

我知道使用new是一种不好的做法,那么有没有一种方法可以使用指针数组而不使用该关键字,或者以后不必使用delete

如果我们坚持使用"classic"C++(而不是最新的出血边缘标准),那么就没有unique_ptr或std::array,使用new是正常的。它会带来一些存储泄漏(无法删除)或存储损坏(删除两次)的风险,但您的工作是编写代码以避免这些问题。

然而,有一些使用new的方法不太可能导致内存泄漏,如下所示。注意:这不是完全安全的生产代码,只是一个教程示例,介绍如何使用带析构函数的类来管理用new分配的存储的生存期。

class WithAnArray {
     private:
        int *storage;
     public:
        WithAnArray(unsigned size) {
           storage = new int[size];
        }
        ~WithAnArray() {
           delete[] storage;
        }
        int* getArray() {
           return storage;
        }
 }

C++11引入了std::array:-)这是一种回避问题的方法吗?:-):-)

描述为:

std::array是一个封装常量大小数组的容器。

使用示例:

std::array<int, 3> a2 = {1, 2, 3};

或者,您甚至可以使用std::unique_ptr,如本例所示:

int size = 10; 
std::unique_ptr<int[]> fact(new int[size]);
for (int i = 0; i < size; ++i) {
    fact[i] = (i == 0) ? 1 : i * fact[i-1];
}
for (int i = 0; i < size; ++i) {
    std::cout << i << ": " << fact[i] << 'n';
}

新关键字没有什么不好的,它总是处于动态空间分配的底部,即使您使用std::vector<>和friends也是如此。CCD_ 6等也有其问题。但事实并非如此,我的答案是关于这一点的。

我的答案是关于出于性能原因需要避免new的情况(这是一个非常昂贵的运算符,需要几百个周期)。

您通常可以避免逐行分配数组,只需一次性分配所有数组,并手动构建所需的指针结构:

size_t fieldSize = width*height*sizeof(int);
size_t pointerArraySize = height*sizeof(int*);
char* memory = new char[fieldSize + pointerArraySize];
int** pointerArray = (int**)memory;
int* dataArray = (int*)&memory[pointerArraySize];
for(long i = height; i--; ) pointerArray[i] = &dataArray[i*width];

好吧,这比进行许多单独的分配要麻烦一些,但速度要快得多。而且,作为一个额外的好处,交易是一句话:

delete[] (char*)pointerArray;

问题是size在编译时已知(可以计算)还是仅在运行时已知。

如果第一种情况适用,请使用std::array,对于后者,不可能不使用new(间接)或传递给STL容器的某个分配器代理(例如std::vector)。

您可以直接传递对一个大小为巨大数字的静态数组的引用。

任何声称使用new是不好的做法的人都不应该被允许开发任何代码,因为如果我们扩大这种说服力,那么使用指针也是不好的,使用/开发COM对象也是不好,使用堆也是不好。。。在这种煽动的最后,很可能是"使用电脑是一种糟糕的做法,让我们切换到石器时代"。

如果你不知道如何在不造成混乱的情况下使用new/delete,那就雇佣一个知道的人。