为什么我们可以删除数组,但不知道C/C++中的长度?

Cas*_*ash 18 c c++ arrays

我们有可能删除动态分配的数组,但我们无法找出它们有多少个元素?我们不能只根据每个对象的大小来划分内存位置的大小吗?

Ton*_*roy 16

在C++中,两者都......

  • 新的,new []或malloc调用所请求的大小(字节),以及
  • new []动态分配中请求的数组元素数

...是标准不需要以编程方式提供的实现细节,即使内存分配库必须记住前者和编译器后者,因此它可以在正确数量的元素上调用析构函数.

有时编译器可能会看到有一个恒定大小的分配,并且能够可靠地将其与相应的释放相关联,因此它可以生成为这些编译时已知值定制的代码(例如内联和循环展开),但是在复杂的使用中(当处理外部输入时,编译器可能需要在运行时存储和检索#个元素:#element计数器的足够空间可能会被放置 - 例如 - 紧接在为数组内容返回的地址之前或之后,删除[]了解这个惯例.在实践中,编译器可能会选择始终在运行时处理此问题,只是为了简化一致性.存在其他运行时可能性:例如

标准不提供编程访问,以确保实现在他们可能使用的优化(速度和/或空间)中不受约束.

(内存位置的大小可能大于所请求数量的元素所需的确切大小 - 内存分配库会记住该大小,该内存分配库可能是独立于C++编译器的黑盒库).

  • @Matthieu:"因为析构函数应该被运行,这意味着必须知道元素的数量" - 如果包含的数组类型具有可以执行任何操作的析构函数.作为优化,C++实现可以存储为`std :: string []`请求的元素数,但不存储它为`int []`.我认为用于检索大小的API要么必须在其工作时制定,要么在不工作时制定,否则实际上将禁止优化. (4认同)
  • @Matthieu M.:真的,C++是由C形成的,尽管C++是基于需求,机会,反馈和解决问题而演变而来的.如果程序员一直要求这个 - 并且可以证明实用性 - 它可能很久以前就已经可用了,只要实施者没有对工作或现有的优化大声喧哗.无论如何,万岁std :: vector():-). (2认同)

Fre*_*Foo 6

内存分配器会记住分配的大小,但不会将其提供给用户.这在C with malloc和C++中都是如此new.

"无法获得"内存位置的大小".如果你这样做

int *a = new int[N];
std::cout << sizeof(a);
Run Code Online (Sandbox Code Playgroud)

你会发现它打印sizeof(int *),这是不变的(对于给定的平台).


MOn*_*DaR 5

C++中常见的方法是使用std::vector而不是数组.

std::vector具有size返回元素数量的方法.

如果可能,您应该尽可能使用std::vector而不是使用数组.