Допустим, мы начинаем с:
int *newArray = new int[1];
А потом позже есть что-то вроде:
ifstream inputFile("File.txt");
Counter=0;
while (inputFile >> newValue)
{
newArray[Counter] = newValue;
Counter++
}
Если я попытаюсь вытащить 100 строк из текстового файла, программа в конечном итоге вылетит. Однако, если бы я использовал
int *newArray = new int[100];
Первоначально он не падает.
Если он динамически распределяет память, зачем ему начальное значение больше 1? Это не имеет смысла для меня. Необходимость определить любую начальную длину за небольшим числом, например, 1 или 10, отрицательно сказывается на цели динамического выделения памяти …
РЕДАКТИРОВАТЬ: Это для школы, нам еще не разрешено использовать векторы.
Он не динамический в том смысле, что он может динамически изменять свой размер. Он динамический в том смысле, что его размер можно выбирать динамически во время выполнения, а не во время компиляции. Одна из основных философий C ++ заключается в том, что вы не платите за то, что не используете. Если бы динамические массивы работали так, как вы просите, это потребовало бы проверки границ, чего-то, что мне не нужно, поэтому я не хочу за это платить.
В любом случае, проблема решена с помощью стандартной библиотеки.
std::vector<int> vec;
...
while (inputFile >> newValue)
{
vec.push_back(newValue);
}
Разве это не намного лучше? Вам даже не нужно отслеживать размер, потому что вектор отслеживает его для вас.
Если вы не можете использовать вектор, то у вас впереди много работы. Принцип по сути это. Вы сохраняете 2 дополнительные целочисленные переменные. Один, чтобы указать количество значений, которые вы используете в вашем массиве, и один, чтобы указать текущую емкость вашего массива. Когда вам не хватает места, вы выделяете больше места. Например, вот небезопасная версия вектора бедного человека без исключений:
int size = 0;
int capacity = 1;
int array = new int[capacity];
while (inputFile >> newValue)
{
if (size == capacity)
{
capacity *= 2;
int * newArray = new int[capacity];
for (int i=0; i<size; ++i)
newArray[i] = array[i];
delete [] array;
array = newArray;
}
array[size++] = newValue;
}
Язык не будет «динамически выделять память» для вас. Вы несете ответственность за распределение и перераспределение массивов таким образом, чтобы их размеры были достаточными для ваших целей.
Концепция «динамического выделения» в C ++ никогда не означала, что память каким-то образом автоматически выделяется для вас. Слово «динамический» в этом контексте просто означает, что параметры и время жизни нового объекта определяются во время выполнения (в отличие от времени компиляции). Основное назначение динамического выделения памяти: 1) ручное управление временем жизни объекта, 2) указание размеров массива во время выполнения, 3) определение типов объектов во время выполнения.
Второй момент заключается в том, что позволяет вам сделать это
int n = ...; // <- some run-time value
int *array = new int[n];
что невозможно с нединамически размещенными массивами.
В вашем примере вы можете выделить массив, если размер 1 изначально. В этом нет ничего плохого. Но вы по-прежнему несете ответственность за выделение нового, большего массива, копирование данных в новый массив и освобождение старого, как только вам понадобится больше места в вашем массиве.
Чтобы избежать всех этих хлопот, вы должны просто использовать предоставляемый библиотекой изменяемый размер контейнера, например std::vector
,
Вы создаете пространство только для одного int
но, пытаясь сохранить несколько, конечно, вылетает. Даже если вы создали его с размером 100, он все равно потерпит крах, когда вы попытаетесь сохранить 101-е значение.
Если вам нужен автоматически изменяющий размер контейнер, проверьте std::vector
,
#include <vector>
std::vector<int> data;
while (inputFile >> newValue)
{
data.push_back(newValue);
}
Это будет работать до тех пор, пока вашему процессу не хватит памяти.