嗯,我不认为它真的很重要,但由于程序必须存储长度因为删除[],为什么我们不能得到这个“存储信息”?
答案 0 :(得分:9)
实现只需要存储长度,并且通常只有,如果类型不是简单的可破坏的(即,它需要生成对析构函数的调用)并且数组是使用new []运算符创建的。
由于数组类型的属性与数组的大小无关,因此将长度“cookie”称为私有实现细节更为优雅。
要获取完整数组对象(不仅仅是指针)的长度,可以使用std::extent< decltype( arr ) >::value
或std::end( arr ) - std::begin( arr )
。
将new[]
与带有析构函数的类一起使用是一种代码气味。请考虑使用std::vector
。开销与原始new[]
(考虑所有需要分配的字节,无论它们在哪里)都是一个指针的字节值,其好处是无数的。
答案 1 :(得分:2)
考虑这个案例:
char* a = new char[100];
现在a
需要指向一个至少100个字符大的缓冲区,但是系统可能已经分配了一个更大的缓冲区来实现这个。
考虑到这一点,我们可以看到系统可以立即忘记程序要求的大小,只要它以后仍然可以正确释放缓冲区。 (通过记住分配的缓冲区的大小或使用某些智能数据结构进行内存分配,其中只需要指向start的指针)
因此,在一般情况下,您要查找的信息不,实际上存储在任何地方。
答案 2 :(得分:1)
并非所有数组都由new
分配。
void f(int* arr, size_t n)
{
length(arr); // ???
}
int main()
{
int a[5];
f(a);
}
尽管只是调用(std::end(arr) - std::begin(arr))
,但是它只能用于数组,而不是指向数组开头的指针。
答案 3 :(得分:1)
我的理解是,c ++的哲学是不要强迫任何具有潜在成本的特征,除非不可避免。
存储此信息可能会产生额外费用,如果用户不需要这些信息,则可能不想支付该费用。因为如果你想要它自己存储长度是微不足道的,所以没有理由提供一个语言功能,每个人使用数组都有成本。
答案 4 :(得分:1)
对于正确的数组,即int a[length]
,您已经拥有该功能:只需执行
#define length(A) (sizeof(A) / sizeof(*A))
你完成了它。
如果你在谈论获取指针所指向的数组的长度,那么,指针和数组是两个不同的概念,并且它们的耦合是没有意义的,即使适当的数组在需要时“衰减”到指针并且你访问它们数组通过指针算术。
但即使我们没有考虑到这一点并讨论技术方面,C++
运行时可能也不知道数组的长度是多少,因为new
可能依赖{{1}它以特定的方式存储数组的长度,只有malloc
才能理解:free
运行时仅在存在非空的析构函数时才存储额外的信息。一张相当混乱的照片,嗯?
答案 5 :(得分:0)
因为它存储了这些信息的实现。所以没有通用的方法来做长度(数组)
答案 6 :(得分:0)
长度肯定不会存储在所有实现中。例如,C ++允许垃圾收集(例如boehmgc),并且许多收集器不需要知道长度。在传统的分配器中,存储的长度通常大于实际长度,即分配的长度,而不是使用的长度。
答案 7 :(得分:0)
但是,阵列的长度究竟是多少?它是数组中的字节数还是数组中的元素数?
例如:对于某个100字节大小的A类,
A * myArray = new A [100];
长度(myArray)应该返回100还是100 * 100?有人可能想要100,有人可能想要10000.所以,对于其中任何一个都没有真正的论据。
答案 8 :(得分:0)
与支持length(array)
的语言中的“数组”最相似的c ++类型是std::vector<>
,而 的{c}类型std::vector<>::size()
。
编译器在大小明确的作用域中知道普通[]
数组的大小,但是可以将它们传递给大小为而不是的作用域编译器已知。这使得c ++ 更多方法可以处理类似数组的数据,而不是必须支持length
interogative的语言(因为它们必须确保总是传递大小)。