如何在C++中获取动态数组的大小

21

我想通过一个模板方法获取动态数组的长度,而不是像之前那样,通过输入大小并将其存储到“n”变量中。

int* a = NULL;   // Pointer to int, initialize to nothing.
int n;           // Size needed for array
cin >> n;        // Read in the size
a = new int[n];  // Allocate n ints and save ptr in a.
for (int i=0; i<n; i++) {
    a[i] = 0;    // Initialize all elements to zero.
}
. . .  // Use a as a normal array
delete [] a;  // When done, free memory pointed to by a.
a = NULL;     // Clear a to prevent using invalid memory reference.

以下是类似的代码,但使用了动态数组:

#include <cstddef>
#include <iostream>
template< typename T, std::size_t N > inline
std::size_t size( T(&)[N] ) { return N ; }
int main()
{
     int a[] = { 0, 1, 2, 3, 4, 5, 6 };
     const void* b[] = { a, a+1, a+2, a+3 };
     std::cout << size(a) << '\t' << size(b) << '\n' ;
}

2
你需要记住大小,仅从指针中无法获取大小。 - πάντα ῥεῖ
3
建议使用 std::vector 而不是自己操作指针。如果你真的想要操作指针,那么回答是不行的。所以不要这样做。 - Mike Seymour
原始数组很蠢,它们不知道自己有多少个元素。使用“向量”(vector)。 - Fredrick Gauss
@FredrickGauss 在C++中,原始数组具有包含大小信息的类型。这是一个不同的问题:从new获得的只是指向数组第一个元素的指针。 - juanchopanza
2
如果我们希望在语言中具有类型感知能力,那么就返回一个数组的第一个元素的指针。 - Lightness Races in Orbit
显示剩余2条评论
1个回答

48

不可能。使用new[]分配的数组大小未以任何可以访问的方式存储。注意,new []的返回类型并不是一个数组——它是一个指针(指向数组的第一个元素)。因此,如果您需要知道动态数组的长度,则必须单独存储长度。

当然,正确的做法是避免使用new[],而是使用std::vector,它会为您存储长度,并且还具有异常安全性。

以下是您使用std::vector而不是new[]的代码示例:

size_t n;        // Size needed for array - size_t is the proper type for that
cin >> n;        // Read in the size
std::vector<int> a(n, 0);  // Create vector of n elements initialised to 0
. . .  // Use a as a normal array
// Its size can be obtained by a.size()
// If you need access to the underlying array (for C APIs, for example), use a.data()

// Note: no need to deallocate anything manually here

3
我不确定为什么这篇文章被踩了,实际上,我确定我不明白…… - Lightness Races in Orbit
4
我观察到无故投反对票与没有留下评论/建议来改进/修正答案之间存在强烈的相关性。 - juanchopanza
1
@evergreen 我已经扩展了答案,展示了使用std::vector而不是new[]的代码。 - Angew is no longer proud of SO
4
你可以这么说:在C++中,"动态数组"的正确写法是 std::vector,而不是 T* array = new T[]。强调一遍,几乎没有理由使用数组new(或者至少非常少见——但我已经使用C++超过20年了,从未找到适合数组new的情况)。 - James Kanze
1
@Angew 任何合理的向量类(标准要求std::vector)都会分离分配和初始化,可能会使用std::operator new()函数和放置new。否则,您最终将不得不默认构造所有元素,然后对它们进行赋值,而不是立即使用所需的初始化程序构造它们。(当我开始学习C++时,还没有std::vector,当然,第一件事就是编写自己的向量和字符串类。) - James Kanze
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接