Почему начальная длина не может быть 1 в динамически распределенном массиве?

Допустим, мы начинаем с:

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, отрицательно сказывается на цели динамического выделения памяти …

РЕДАКТИРОВАТЬ: Это для школы, нам еще не разрешено использовать векторы.

0

Решение

Он не динамический в том смысле, что он может динамически изменять свой размер. Он динамический в том смысле, что его размер можно выбирать динамически во время выполнения, а не во время компиляции. Одна из основных философий 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;
}
1

Другие решения

Язык не будет «динамически выделять память» для вас. Вы несете ответственность за распределение и перераспределение массивов таким образом, чтобы их размеры были достаточными для ваших целей.

Концепция «динамического выделения» в C ++ никогда не означала, что память каким-то образом автоматически выделяется для вас. Слово «динамический» в этом контексте просто означает, что параметры и время жизни нового объекта определяются во время выполнения (в отличие от времени компиляции). Основное назначение динамического выделения памяти: 1) ручное управление временем жизни объекта, 2) указание размеров массива во время выполнения, 3) определение типов объектов во время выполнения.

Второй момент заключается в том, что позволяет вам сделать это

int n = ...; // <- some run-time value
int *array = new int[n];

что невозможно с нединамически размещенными массивами.

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

Чтобы избежать всех этих хлопот, вы должны просто использовать предоставляемый библиотекой изменяемый размер контейнера, например std::vector,

4

Вы создаете пространство только для одного int но, пытаясь сохранить несколько, конечно, вылетает. Даже если вы создали его с размером 100, он все равно потерпит крах, когда вы попытаетесь сохранить 101-е значение.

Если вам нужен автоматически изменяющий размер контейнер, проверьте std::vector,

#include <vector>

std::vector<int> data;

while (inputFile >> newValue)
{
data.push_back(newValue);
}

Это будет работать до тех пор, пока вашему процессу не хватит памяти.

0
По вопросам рекламы [email protected]