这是我的代码:
int *arr1 = new int[size]();
int *arr2 = new int[size]();
int *arr3 = new int[size]();
我知道,我知道:如果我需要使用指针,我应该使用std::unique_ptr
,但我需要通过赋值来使用*数组(使用“动态分配” - 我会使用{{1}但由于某种原因,这是不允许的。)
我知道使用std::vector
是不好的做法,那么有没有办法在不使用该关键字的情况下使用指针数组,或者稍后必须执行new
?
答案 0 :(得分:4)
如果我们坚持'经典'C ++(而不是最新的前沿标准),那么你没有unique_ptr或std :: array,并且使用new是正常的。它存在泄漏存储(通过无法删除)或损坏存储(通过删除两次)的一些风险,但是为了避免这些问题而编写代码是你的工作。
但是,有一些方法可以使用不太可能导致内存泄漏的新方法,如下所示。注意:这不是完全安全的生产代码,只是一个关于使用带析构函数的类来管理使用new分配的存储生命周期的教程示例。
class WithAnArray {
private:
int *storage;
public:
WithAnArray(unsigned size) {
storage = new int[size];
}
~WithAnArray() {
delete[] storage;
}
int* getArray() {
return storage;
}
}
答案 1 :(得分:2)
C ++ 11引入std::array :-)是否可以回避这个问题? :-): - )
描述如下:
std :: array是一个封装常量数组的容器。
使用示例:
std::array<int, 3> a2 = {1, 2, 3};
或者您甚至可以使用std::unique_ptr,例如this示例:
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';
}
答案 2 :(得分:1)
新关键字没什么不好,即使您使用std::vector<>
和朋友,它也始终位于动态空间分配的底部。 std::unique_ptr
这样也存在问题。但这不是,我的回答是什么。
我的答案是关于这些情况,出于性能原因需要避免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;
答案 3 :(得分:0)
问题是在编译时或仅在运行时知道{可以计算} size
。
如果第一种情况适用,请使用std::array
,后者没有办法不使用new
(间接)或某些分配器代理传递给STL容器(例如std::vector
)。
答案 4 :(得分:0)
你可以将引用传递给一个大数字的静态数组。
答案 5 :(得分:0)
任何人声称使用new是不好的做法不应该被允许开发任何代码,因为如果我们扩展这样的说服,那么使用指针也很糟糕,使用/开发COM对象也很糟糕,使用堆也很糟糕。 ..在蛊惑人心的最后,很可能就像“使用电脑是不好的做法,让我们转向石器时代”。
如果你不知道如何使用new / delete而不造成混乱,请聘请一些人。