我正在学习C ++阅读Stroustrup的书,我认为在这个主题(数组)中并不是很清楚。据我所知,C ++(如Delphi)有两种数组:
声明为的静态数组
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 :(得分: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, 然后你会得到一个分段错误。程序将编译,但当它到达一个使它超出数组边界的语句时会崩溃。
通常,当您拥有大型代码时,不经常使用数组。向量在几乎所有方面都是客观上优越的,因此使用数组变得毫无意义。
编辑:正如Paul McKenzie在评论中指出的那样,走出数组边界并不能保证分段错误,而是未定义的行为,并由编译器决定发生了什么答案 1 :(得分:2)
让我们以从文件中读取数字为例 我们不知道文件中有多少个数字。
要声明一个数组来保存数字,我们需要知道容量或数量,这是未知的。我们可以选择64之类的数字。如果文件有超过64个数字,我们就开始覆盖数组。如果文件少于64(如16),我们就会浪费内存(不使用48个插槽)。我们需要的是动态调整容器(数组)的大小。
要动态调整数组的容量,必须创建一个新的更大的数组,然后复制元素并删除旧数组。
std::vector
会根据需要调整其容量。它为您处理内存的动态分配。
另一个方面是将容器传递给函数。使用数组,您需要传递数组和容量。使用std::vector
,您只需传递矢量。可以查询向量对象的容量。
答案 2 :(得分:-4)
我可以看到的一个安全措施是,您无法访问不存在的向量中的内容。
我的意思是,如果你只推送4个元素而你试图访问索引7,那么它会抛出一个错误。但是阵列并没有发生。
简而言之,它阻止您访问损坏的数据。
程序员必须将索引与vector.size()进行比较才能抛出错误。并且它不会自动地发挥作用。一个人必须自己做。