4

我有一个带有静态链接的 C++ 全局多维数组。我假设它将被堆栈分配(我在标准中找不到相关部分)。它是连续分配的吗?

另一个问题:我想将这些静态全局 n-dim 数组转换为在堆上分配。考虑到我想最小化代码更改,最简单的方法是什么?我可以考虑将数组转换为 n-dim 指针并在 main 开始时 malloc'ing 并在退出 main 之前释放。但我不得不担心连续分配。有人看到更好的方法吗?

谢谢,

尼莱什。

4

3 回答 3

2

我有一个带有静态链接的 C++ 全局多维数组。我假设它将被堆栈分配(我在标准中找不到相关部分)。

它不会在堆栈上;它将在全球范围内。全局对象和静态存储对象拥有自己的内存区域,既不属于堆也不属于堆栈。

此外,堆栈(标准将其称为“自动”存储)对象仅在它们所属的函数调用期间持续存在;全局变量在被调用之前被初始化并在退出main()后被销毁。main()

它是连续分配的吗?

可能是,尽管我怀疑标准是否需要它。(澄清:保证一维数组的连续存储,但不能保证二维数组和向上数组中的行之间没有“间隙”。)如果您需要连续分配,请将全局数组声明为一个-维向量并使用内联函数将多个维度转换为相应的索引。如果保证连续存储,它与编译器生成的内容相同。

我想将这些静态全局 n-dim 数组转换为在堆上分配。考虑到我想最小化代码更改,最简单的方法是什么?

将全局声明从数组更改为指针。在这种情况下,强烈建议对存储进行矢量化。(不,我不是在谈论std::vector,我是在谈论重塑为一维向量。)

我可以考虑将数组转换为 n-dim 指针

没有这样的野兽。关闭事物是指向指针数组的指针,然后指向向量或更多指针的数组,深度由维数决定。使用将 ND 坐标转换为 1-D 索引的函数来设置上述 1-d 矢量情况将是一种负担,而且比上述情况要慢得多。

在 main 开始时 malloc'ing,在退出 main 之前 free'ing。

这一点,除非您最后不必这样做,free除非您正在使用valgrind或类似的方法来查找内存泄漏。操作系统在进程退出时释放所有不是共享内存的分配。

所以你会得到类似的东西:

#include <stddef.h>

static const size_t kDimX = 5;
static const size_t kDimY = 20;
static const size_t kDimZ = 4;

inline size_t DimsToVector(size_t x, size_t y, size_t z)
{
    return (x * kDimY + y) * kDimZ + z;
}

float* data = 0;

int main()
{
    data = new float[kDimX * kDimY * kDimZ];

    // Read elements with: data[DimsToVector(x, y, z)]
    // Write v with: data[DimsToVector(x, y, z)] = k;

    delete[] data; // Optional.
}

有一些更好的方法,可能是 Boost 中的一种,它定义类并覆盖operator []以隐藏一些丑陋的东西,但这是让你开始的最低限度。

于 2012-05-16T21:38:11.780 回答
1

它没有在堆栈上分配。全局变量被“分配”在一个特殊的内存段中。

至于使您的多维数组“连续”,我能想到的最简单的可靠方法是在不与类型系统进行太多斗争的情况下制作typedef较低维度的 a 并制作指向该类型的指针。

typedef int TenIntegers[10];
TenIntegers* ints;

int main()
{
    ints = new TenIntegers[50];

    // your code here
    ints[0][5] = 3;

    delete[] ints;
}
于 2012-05-16T21:22:54.023 回答
0

1)全局变量的内存分配在“内存中”的某个地方。它既不在堆栈上,也不在堆上。例如,全局常量通常放在可执行文件的只读部分。严格来说,它依赖于实现。为什么你需要知道这个?

2)记忆将是连续的。

于 2012-05-16T21:29:23.920 回答