2016-12-06 108 views
1

我正在学习C++阅读Stroustrup的书,在我看来,这个主题不是很清楚(数组)。从我所了解C++有(如德尔福)两种阵列:动态和静态数组

静态数组被声明如下

int test[3] = {10,487,-22}; 

动态数组被称为矢量

std::vector<int> a; 

a.push_back(10); 
a.push_back(487); 
a.push_back(-22); 

我已经看到有关这方面的答案(并且里面有很多线条和概念),但他们没有向我阐明这个概念。


从我所了解vector小号占用更多的内存,但他们可以改变它们的大小(动态,其实)。数组在编译时具有固定的大小。

在章节Stroustrup说,矢量是安全的,而数组不是,但没有解释原因。我确实相信他,但为什么?记忆的位置是否与安全有关? (堆/栈)

我想知道为什么我使用载体,如果他们是安全的。

+0

这是一个非常广泛的讨论,如果你问使用std :: vector,数组和指针的优点和陷阱。 –

+0

在我的代码中,我将使用向量总是和数组,只有当我发现有人在旧版本中使用它们时。但我想知道为什么 –

+0

std :: vector是一个很好的机器,已经接管了以前用数组解决的大多数任务。你会想研究std :: vector是如何设计的以及为什么。这包括资源管理(3/5规则)以及算法行为。 –

回答

3

数组不安全的原因是内存泄漏。

如果声明一个动态数组

int * arr = new int[size] 

和你不这样做删除[] ARR,则存储器保持未清除的,这就是所谓的内存泄漏。需要注意的是,任何时候当你在C++中使用new这个词时,都必须有一个删除的地方来释放这个内存。如果你使用malloc(),那么应该使用free()。

http://ptolemy.eecs.berkeley.edu/ptolemyclassic/almagest/docs/prog/html/ptlang.doc7.html

这也是非常容易去出界在阵列中,例如,在比其尺寸大-1的索引插入的值。使用矢量,可以根据需要push_back()尽可能多的元素,矢量将自动调整大小。如果你有一个大小为15的数组,你试图说arr [18] = x, 然后你会得到一个分段错误。该程序将编译,但当它达到一个声明将其置于数组边界之外时将会崩溃。

一般来说,当你有大的代码时,数组很少使用。几乎在所有方面,矢量在客观上都非常优越,所以使用数组变得毫无意义。

编辑:正如保罗·麦肯齐在评论中指出,走出去的数组边界不保证分段错误,而是不确定的行为,要由编译器来确定发生了什么

+0

他们需要更多的空间是的,但总的来说,我应该更喜欢矢量。我想我已经理解了“安全”在哪里:)也可以用很多有用的方法实现向量;阵列是“古老的”,可用于C复古兼容性 –

+0

这是事实。向量使用更多的存储空间,但与载体带来的安全/效率优势相比,这是模糊的。 –

+2

@ConnorSchwinghammer - *如果你有一个大小为15的数组,并且你试图说arr [18] = x,那么你会得到一个分段错误* - 如果你使用'[]'向量跳出界限(是的,调试Visual C++运行时会检查,而不是发布版本),你不能保证出现分段错误。所以,当你走出界限时,你基本上可能会遇到与使用常规数组相同的未定义行为。然而'vector'有'at()'函数,这保证了如果索引超出范围,就会抛出一个'std :: out_of_range'异常。所以也许你应该修改你的答案? – PaulMcKenzie

-4

我可以看到的一个安全性是,你不能访问不存在的向量中的东西。

我的意思是,如果你push_back只有4个元素,并且你试图访问索引7,那么它会抛出一个错误。但在阵列中并没有发生。

总之,它阻止你访问损坏的数据。

编辑:

程序员必须比较vector.size()指数抛出一个错误。它不会自动开心。一个人必须自己做。

+0

在大多数情况下这是不真实的。 –

+0

@CaptainGiraffe,我的意思是像之前使用任何索引号,我们可以将它与vector.size()进行比较,并且我们可以决定它是否超出限制。 –

+0

任何合理使用数组的情况也是如此。 –

2

让我们以从文件读取数字的情况。
我们不知道文件中有多少个数字。

要声明一个数组来保存数字,我们需要知道容量或数量,这是未知的。我们可以选择一个数字,如64.如果文件的数量超过64,我们将开始覆盖数组。如果文件少于64个(如16),我们浪费内存(不使用48个插槽)。我们需要的是动态调整容器(数组)的大小。

要动态调整数组的容量,必须创建一个新的更大的数组,然后复制元素并删除旧数组。

std::vector将根据需要调整其容量。它为你处理动态的内存分配。

另一方面是将容器传递给函数。有了数组,你需要传递数组和容量。用std::vector,你只需要传递向量。可以查询矢量对象的容量。