动态数组和STL向量的确切区别是什么?

14

动态数组和向量之间的确切区别是什么?这是我在面试中遇到的问题。

  1. 我说两者都有顺序内存。

  2. 向量可以在代码任何时候增长大小。然后他说,即使在创建后,动态数组也可以增长大小。

  3. 我说向量没有错误,因为它在标准库中。他说他会提供一个动态数组的 .so 文件,该文件无误并且具有与 STL 相当的所有特性。

我很困惑,没有回答出确切的区别。当我在互联网上搜索时,我只看到了以上的陈述。

请有人给我解释一下确切的区别吗?面试官对我的期望是什么?

回答: 动态数组和向量都可以在运行时调整大小,但它们的实现方式不同。动态数组是通过手动分配和重新分配内存来实现大小调整的,而向量实际上是基于动态数组的封装和扩展。此外,向量还提供了许多方便的方法和操作符以简化内存管理和访问元素。在 C++ 中,向量是由标准模板库 (STL) 提供的容器类型,已经经过广泛测试和优化,因此通常更安全、可靠且易于使用。因此,如果要选择使用动态数组还是向量,应该优先考虑使用向量。面试官可能希望你能够区分这些概念并解释它们的实现方式和优缺点。

3
你忘记了编译器附带的大型算法库。 - DumbCoder
请参见https://dev59.com/6HRC5IYBdhLWcg3wMd9S。 - moooeeeep
哦不..我说过没有错误..我之前写错了,现在已经更正。 - Rajesh
1
@DumbCoder:那是所有通用代码,可以接受任何类似迭代器的东西,甚至是手工制作的动态数组中的普通指针。 - sbi
你应该问面试官他所说的动态数组是什么意思。我认为他想看看你有多好奇。 - nikhil
7个回答

16
他说他将提供一个 .so 的动态数组文件,该文件无误并具有与 STL 相当的所有质量。
如果他的动态数组类与 std::vector 做的一样(也就是说:它实现了 RAII 以清理自己,可以增长和缩小以及其他 std::vector 所做的任何事情),那么 std::vector 只有一个重要优势超过他的动态数组类:
std::vector 是标准化的,每个人都知道它。如果我在某段代码中看到一个 std::vector,我知道它确切地做什么以及应该如何使用它。然而,如果我看到一个 my::dynamic_array,我完全不知道它是什么。我需要查看其文档甚至是实现才能确定 my_dynamic_array::resize() 是否与 std::vector::resize() 做相同的事情。

我认为这里的动态数组并不是指一个类,而只是使用 new[] 动态分配的数组。 - Alok Save
1
@Als: "动态数组具有与STL相当的所有特性"。您不能在不创建类的情况下做到这一点。 - sbi
同意。鉴于该声明,唯一的区别在于标准化版本和非标准化版本。 - Alok Save
@Rajesh:那么你应该问面试官,你的类提供什么功能?它有多安全?实现细节是什么?你不能将苹果和梨进行比较,你首先必须确定他是否要求你将一个好的苹果与不太好的苹果或梨进行比较。而这只能通过向他提出正确的问题来完成。 - Alok Save
@Als:它具有与STL相当的所有特点。这回答了所有那些问题。 - sbi
显示剩余3条评论

6
很大程度上取决于他所说的“动态数组”的含义。大多数人指的是使用array-new分配内存并使用array-delete释放内存的东西。如果这是意图,那么要想拥有与std::vector相当的质量是不可能的。
原因很简单:std::vector通常会分配比当前存储的元素数量更大的内存块。然后根据需要在该内存中构造对象以进行扩展。但是,使用array-new时,你没有选择——你正在分配一个对象数组,因此如果你为(假设)100个对象分配空间,则会立即在该空间中创建100个对象。它根本没有提供另一部分只包含实际对象的缓冲区和另一部分只包含普通内存的方法。
我想,如果你想要牵强一点,仍然可以使用array-new来模仿std::vector并分配空间。为此,你只需分配一个char数组,然后使用placement new在该原始内存空间中创建对象。这几乎允许与std::vector相同的事情,因为它实际上与std::vector几乎相同。然而,我们仍然缺少(潜在的)间接级别——std::vector实际上通过Allocator对象分配内存,因此您可以精确地更改它如何分配其原始内存(默认情况下,它使用std::allocator ,它使用operator new,但如果您想要的话,您实际上可以编写一个分配器,它将使用new char [size],尽管我无法想象为什么会这样做)。
当然,你也可以编写你自己的动态数组来使用一个allocator对象。在那种情况下,就所有实际目的而言,你只是用一个(可能)新的名字重新发明了std::vector。即使忽略标准化,@sbi依然正确:它没有被标准化的事实意味着它仍然缺少std::vector的主要特性之一——作为已经为每个知道C ++的人所知的质量。即使我们忽略标准化,我们必须把“动态数组”这个短语拉到(我认为)极限才能获得与std::vector相同的质量。

2

我想他们希望你谈论忘记使用operator delete[]删除动态数组的陷阱,但当他们试图帮助你时,他们自己也感到困惑了;将动态数组实现为普通类并不太合理,因为它内置了元素类型。


0

当向量在堆栈上声明时(支撑数组将在堆上),为向量分配的数组内存将在向量超出范围时释放。

void foo() {
  vector<int> v;

  // ... method body

  // backing array will be freed here
}

0
也许问题出在动态数组上,每当你想要调整大小时,你需要将其复制到一个新的动态数组中,但是你可以根据对数据的了解来控制它何时进行调整。
而向量使用相同的过程,但向量不知道以后是否会增长,因此它可能为可能的大小增长分配额外的存储空间,因此与动态数组相比,它可能会占用更多的内存空间来管理自身。
因此,我认为区别在于当管理大小不是大问题时使用向量,而当你宁愿自己调整大小时则使用动态数组。

0

0
  1. 如果定义为动态数组,则必须显式释放数组,而向量会自动从堆内存中释放。

  2. 如果动态分配,则无法确定数组的大小,而可以在O(1)时间内确定向量的大小。

3.当将数组传递给函数时,还需要单独传递大小参数,而在将向量传递给函数时,由于向量始终保持跟踪容器大小的变量,因此不需要这样做。

4.当我们动态分配数组后,初始化大小后就无法更改其大小,而在向量中我们可以这样做。


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