gpt4 book ai didi

c++ - 数组作为模板参数 : stack or heap?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:27:22 25 4
gpt4 key购买 nike

与堆相比,我对堆栈的了解非常初级,但是当涉及到数组时,据我所知,在堆栈上创建了这样的东西

float x[100];

而像这样的东西是在堆上创建的

float* x = new float[100];

但是,如果我创建一个模板数组类,并以“堆栈”数组类型(如 float[100])传递它,会发生什么情况?示例:

#include <iostream>

using namespace std;

template <class T>
class Array {
public:
int size;
T* data;

Array(int size_) : size(size_) {
data = new T[size];
}

~Array() {
delete [] data;
}
};

int main() {
int m = 1000000;
const int n = 100;
Array<float[n]>* array = new Array<float[n]>(m);

for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
array->data[i][j] = i * j;

cout << array->data[10][9] << endl;
delete array;
}

这里到底发生了什么?这个内存是在栈上创建的,还是在堆上创建的?我猜是堆,但它是如何工作的呢?编译器是否分配一大块内存,然后存储指针,这些指针每 n 个元素索引到其中?或者它是否分配许多较小的内存块(不一定是连续的),并存储指向每个 block 的指针?

此外,如果没有模板的帮助,我似乎无法做到这一点。具体来说,这段代码无法编译:

int m = 1000;
const int n = 100;
(float[n])* array = new (float[n])[m];

这是怎么回事?

编辑:

感谢大家提供语法提示。我真正感兴趣的是区 block 中发生的事情

int m = 1000;
const int n = 100;
float (*array)[n] = new float[m][n];

但我不知道不使用模板怎么写。我真正感兴趣的一件事是,如果编译器将其分配为堆上的一个大块,您如何使用语法 array[i][j] 访问特定元素而不存储指向的指针每个第 n 个元素?然后我意识到由于 n 是常量,sizeof(float[n]) 是固定的,所以当你创建数组时,编译器正在分配一个 的数组m 元素,其中每个元素都是一个 float[n],在我的例子中是 100 * 4 = 400 字节。现在一切都说得通了。谢谢!

最佳答案

Array<float[n]>* array = new Array<float[n]>(m);

这里发生的是两次 堆分配。 Array 对象将分配在堆上,因为您使用 new 创建它。 new-expression 调用 Array 构造函数,它再次使用 new 分配数组 data;因此 data 也在堆上分配。

最好这样做:

Array<float[n]> array(m);

这会在堆栈上分配array(因此它将在 block 的末尾自动销毁)。但是,虽然 array 对象本身在堆栈上,但数据仍然存储在堆上,因为它是在 Array 构造函数中分配在堆上的。这类似于您拥有 std::vectorstd::string 局部变量时发生的情况。

Furthermore, I can't seem to do this without the aid of a template. Specifically, this code does not compile:

这只是因为你的语法错误。正确的语法是:

float (*array)[n] = new float[m][n];

左侧显示了声明数组指针的正确方法。对于右侧,您需要一个 m float[n] 数组。这表示为 float[m][n][m] 没有走到最后。

关于c++ - 数组作为模板参数 : stack or heap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24811820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com