2016-12-06 5 views
1

Я изучаю C++, читаю книгу Страуструпа, которая, на мой взгляд, не очень ясна в этой теме (массивы). Из того, что я понял, 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 S потребляют больше памяти, но они могут изменить их размер (динамически, на самом деле). Массивы вместо этого имеют фиксированный размер, который задается во время компиляции.

В главе Struustrup говорится, что векторы безопасны, а массивы - нет, без объяснения причины. Я действительно доверяю ему, но почему? Является ли причина безопасности связана с расположением памяти? (heap/stack)

Я хотел бы знать, почему я использую векторы, если они в безопасности.

+0

Это очень широкое обсуждение, если вы спрашиваете о достоинствах и подводных камнях, используя std :: vector, массивы и указатели. –

+0

В моем коде я буду использовать векторы всегда и массивы, только если я нашел кого-то, кто использовал их в старой версии. Но я хотел бы знать, почему –

+0

std :: vector - хорошо отточенная машина, которая взяла на себя большинство задач, ранее разрешенных с помощью массивов. Вы хотите изучить, как std :: vector разработан и почему. Это включает управление ресурсами (правило 3/5), а также алгоритмическое поведение. –

ответ

3

Причина, по которой массивы небезопасны, связана с утечками памяти.

Если объявить динамический массив

int * arr = new int[size] 

и не делать удаление [] обры, то память остается неубранной, и это известно как утечка памяти. Следует отметить, что в любое время, когда вы используете слово new в C++, там должно быть удаление где-то там, чтобы освободить эту память. Если вы используете malloc(), тогда следует использовать free().

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

Это также очень легко выйти за пределы массива, например, вставки значения в индексе больше, чем его размер -1. С помощью вектора вы можете push_back() столько элементов, сколько хотите, и вектор автоматически изменит размер. Если у вас есть массив размером 15, и вы пытаетесь сказать arr [18] = x, Затем вы получите ошибку сегментации. Программа будет компилироваться, но будет сбой, когда она достигнет инструкции, которая выводит ее из границ массива.

Обычно, когда у вас есть большой код, массивы используются нечасто. Векторы объективно превосходят практически все, и поэтому использование массивов становится бесполезным.

EDIT: Как Пол МакКензи отметил в комментариях, выходя за пределы массива не гарантирует ошибку сегментации, а не определено поведение и до компилятора, чтобы определить, что происходит

+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 вам нужно передать вектор. Объект может быть запрошен о его емкости.

 Смежные вопросы

  • Нет связанных вопросов^_^