c++ 获取std::array的底层数组的内存大小的最简单方法?

bogh5gae  于 2023-10-20  发布在  其他
关注(0)|答案(7)|浏览(146)

这是获取std::array::data()返回的内容在内存中的大小的最简单/最短的方法吗?

arr.size() * sizeof(arr.value_type)

答:我的问题不太准确。通过“内存中的大小”,我的意思是数组中包含的所有元素(本身)的大小,所以如果例如。它们是指向结构的指针,我只需要指针的大小,而不是指向的结构。我也不想包括std::arr实现的任何可能开销的大小。只是数组元素。
有些人建议sizeof(arr)What is the sizeof std::array<char, N>?不同意。虽然它似乎工作在我的机器我想知道什么标准保证。

yzuktlbb

yzuktlbb1#

您可以直接在std::array示例上使用sizeof运算符:

sizeof(arr)

范例:

struct foo
{
    int a;
    char b;
};

int main()
{
    std::array<foo, 10> a;
    static_assert(sizeof(foo) == 8);
    static_assert(sizeof(a) == 80);
}

live example on wandbox
关于cppreference
std::array是封装固定大小数组的容器。
这个容器是一个 * 聚合类型 *,与struct具有相同的语义,它将C风格的数组T[N]作为其唯一的非静态数据成员。

kzipqqlq

kzipqqlq2#

不能保证sizeof(std::array<T,N>) == N*sizeof(T),但可以保证sizeof(std::array<T,N>) >= N*sizeof(T)。额外的大小可能是命名(但未指定)的成员和/或未命名的填充。
保证来自于这样一个事实,即 Package 的T[N]数组必须是std::array<T,N>的第一个成员,但其他成员没有指定。

gwo2fgha

gwo2fgha3#

由于没有人发布任何比我的第一个猜测更好的问题,sizeof(arr)很可能不保证不包括任何可能的额外std::array's字段的大小,我选择这个作为接受的答案。

arr.size() * sizeof(arr.value_type)

如果有人能想出更好的答案,我很乐意接受他们的回答。

oo7oh9g9

oo7oh9g94#

我知道你在问:一个array<value_type,N> arr的元素的集合所占用的内存大小是多少,即在arr.begin()arr.end()之间?
答案是sizeof(value_type)*N,这在标准中有说明,但需要一些处理才能得出这个结论。
在C++标准[dcl.array]中(这是关于(c-)array而不是std::array):
一个数组类型的对象包含一个连续分配的T类型的N个子对象的非空集合。
在[expr.add]中(这里术语array也指(c-)array):
当一个整型的表达式与指针相加或相减时,结果的类型就是指针操作数的类型。如果表达式P指向具有n个元素的数组对象x的元素x[i],则表达式P + J和J + P(其中J具有值j)指向(可能假设的)元素x[i + j],如果0 ≤ i + j ≤ n;否则,行为是未定义的。同样,表达式P-J指向(可能假设的)元素x[i-j],如果0 ≤ i-j ≤ n;否则,行为是未定义的。
在[array.data]中(这里术语数组指的是std::array):

constexpr T* data() noexcept;
constexpr const T* data() const noexcept;
  • Returns*:一个指针,data()== addressof(front()),[data(),data()+ size())是一个有效的范围。

所以data()返回一个有效的范围到std::array的元素,这个范围可以使用指向value_type的指针来迭代,所以它遵循指针算法,该算法遵循(c-)数组索引的规则,并且(c-)数组的元素是连续的。Q.E.D.

mi7gmzs6

mi7gmzs65#

我认为你必须避免使用一个助手函数,

template <typename T>
auto getSize(T& t) -> size_t {
    typename T::size_type size = t.size();
    size_t value_type_size = sizeof(typename T::value_type);

    return size * value_type_size;
}
acruukt9

acruukt96#

如果value_type变得棘手(因为您需要sizeof(decltype(var)::value_type)作为成员大小),那么始终存在data()类型。

std::array<int, 12> var;
size_var = sizeof(*var.data()) * var.size();
std::cout << size_var << std::endl;

在我的机器上输出“48”

igsr9ssn

igsr9ssn7#

读取documentation of std::array。所以是的,很可能是。或者试试

(arr.size()-1) * sizeof(arr.value_type) + sizeof(std::array<T,1>)

但我会用sizeof(arr)
顺便说一句,我不确定你对此有任何正式的保证。我猜想标准理论上允许std::arraystd::vector相同,除了resize()和其他一些方法将被隐藏。但是没有一个合理的实现可以做到这一点(因为std::array已经被发明来将普通数组打包在一个类似于向量的容器中)。
也许一个只允许最多两个元素的std::array-s的实现(但否则会抛出一些异常)可能符合标准的字面意思。

相关问题