int *массив = новый int[n]; что на самом деле делает эта функция?

Я смущен тем, как создать динамически определенный массив:

 int *array = new int[n];

Я понятия не имею, что это делает. Я могу сказать, что он создает указатель с именем array, который указывает на новый объект/массив int? Кто-нибудь захочет объяснить?


person pauliwago    schedule 25.04.2011    source источник


Ответы (8)


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

Затем указатель сохранит адрес в этом блоке памяти.

Но будьте осторожны, этот выделенный блок памяти не будет освобожден, пока вы не сообщите об этом, написав

delete [] array;
person ANisus    schedule 25.04.2011
comment
Могу ли я предложить вам отредактировать это, чтобы сказать что-то вроде, но вместо этого вы должны сделать std::vector<int> array(5);, так как это правильный способ создания такого объекта в C++. - person Aaron McDaid; 12.07.2015
comment
... потому что, например, если функция возвращается раньше (например, возникает исключение), то delete не будет вызываться. По сути, обычные разработчики никогда не должны явно вводить new (или delete) в современном C++. - person Aaron McDaid; 12.07.2015
comment
@AaronMcDaid: Современная версия, безопасная для исключений, будет выглядеть так: std::unique_ptr<int[]> array{new int[n]}; std::vector - это немного больше, чем просто безопасная для исключений версия показанного кода. - person Ben Voigt; 12.07.2015
comment
Моя точка зрения не столько в том, что vector идентично int [n]. Если мы предположим, что нам нужен безопасный для исключений ответ на исходный вопрос, у нас действительно есть только два варианта: unique_ptr<int[]> и vector<int>. Первый может быть «чище», но я уверен, что большинство из нас (включая, возможно, вас?) использовали бы vector для решения реальной проблемы, с которой вопрошающий столкнулся бы сейчас. Мы не знаем полного контекста их текущего задания по программированию, но справедливо поспорить, что vector — это решение, которое использовало бы большинство из нас. - person Aaron McDaid; 12.07.2015

int *array = new int[n];

Он объявляет указатель на динамический массив типа int и размера n.

Чуть более подробный ответ: new выделяет память размером, равным sizeof(int) * n байтам, и возвращает память, которую хранит переменная array. Кроме того, поскольку память динамически выделяется с помощью new, вы должны освободить ее вручную, написав (конечно, когда вам это больше не нужно):

delete []array;

В противном случае ваша программа потеряет память как минимум на sizeof(int) * n байт (возможно, больше, в зависимости от стратегии выделения, используемой реализацией).

person Nawaz    schedule 25.04.2011
comment
Нет, он не инициализирует память нулем. И array на самом деле является указателем на int, а не на массив. И утечка памяти будет как минимум того размера, о котором вы упомянули, но легко может быть и больше. - person ; 25.04.2011
comment
@Nawaz Ссылкой на язык C++ является стандарт C++, а не какой-то написанный вами фрагмент кода, который случайно подтверждает ваше утверждение. - person ; 25.04.2011
comment
@unapersson: Хорошо. Затем см. §5.3.4/15, который начинается с этого ›› Выражение new, создающее объект типа T, инициализирует этот объект следующим образом:[...]. - person Nawaz; 25.04.2011
comment
@unapersson: [..] но может быть и больше.... Почему? Любая ссылка? - person Nawaz; 25.04.2011
comment
s5.3.4/15 утверждает, что если инициализация не выполняется, объект имеет неопределенное значение. В разделе 8.5, в котором указаны правила инициализации по умолчанию, говорится, что для массива без явной инициализации каждый элемент инициализируется по умолчанию. Инициализация по умолчанию для int (очевидно, без конструктора) не выполняет инициализацию. Таким образом, массивы int являются неопределенными. Так что я не думаю, что твой аргумент верен, @Nawaz. - person paxdiablo; 25.04.2011
comment
@paxdiablo и @unapersson: Упс... Я читал non-POD и POD.. они тоже должны писать non с большой буквы. :D... Во всяком случае, я отредактировал пост. - person Nawaz; 25.04.2011
comment
Распределители памяти @Nawaz обычно не выделяют точный размер, который вы запрашиваете, - они выделяют кратно некоторому удобному размеру. Поэтому, если вы запросили f для new int[3], вы могли бы получить 32 байта (например), а не 12 байтов, которые вы могли бы ожидать на платформе, где sizeof(int) равно 4. - person ; 25.04.2011
comment
@unapersson: Это имеет смысл. Но было бы хорошо, если бы вы могли дать ссылку, чтобы я мог узнать ее из конкретного источника (например, стандарта). - person Nawaz; 25.04.2011
comment
@Nawaz В стандарте ничего не говорится о том, как должно быть реализовано распределение памяти. - person ; 25.04.2011
comment
@unapersson, хотя он может выделить больше памяти, чем это, вы не можете использовать какую-либо дополнительную память, не вызывая неопределенного поведения. Следовательно, что касается вас, вы должны исходить из того, что у вас есть только точно то, что вы просили. Единственный раз, когда вы столкнетесь с проблемами, это если вы делаете много небольших распределений, так что потери высоки. - person paxdiablo; 25.04.2011
comment
@paxdiablo: +1 за этот пункт, если вы делаете много небольших распределений, так что потери высоки..... спасибо :-) - person Nawaz; 25.04.2011
comment
@paxdiablo Моя первоначальная точка зрения касалась объема памяти, который, по словам Наваза, просочился, а не законности или иного доступа к этой памяти. - person ; 25.04.2011
comment
@unapersson: Ааа, теперь я понимаю, к чему ты клонишь. Отредактировано, чтобы исправить, надеюсь, вы не возражаете, Наваз. - person paxdiablo; 25.04.2011

Оператор в основном делает следующее:

  1. Создает целочисленный массив из «n» элементов
  2. Выделяет память в памяти HEAP процесса, поскольку вы используете оператор new для создания указателя
  3. Возвращает действительный адрес (если выделение памяти требуемого размера доступно в момент выполнения этого оператора)
person aeon    schedule 25.04.2011

Он выделяет место в куче, равное целочисленному массиву размера N, и возвращает указатель на него, который присваивается указателю типа int*, называемому «массивом».

person DhruvPathak    schedule 25.04.2011

Он выделяет столько места в соответствии со значением n, и указатель будет указывать на массив, то есть на 1-й элемент массива.

int *array = new int[n];
person Saurabh Gokhale    schedule 25.04.2011

В C/C++ указатели и массивы (почти) эквивалентны. int *a; a[0]; вернет *a, а a[1]; вернет *(a + 1)

Но массив не может изменить указатель, на который он указывает, в то время как указатель может.

new int[n] выделит несколько пробелов для "массива"

person LLS    schedule 25.04.2011

new оператор выделяет место для блока из n целых чисел и назначает адрес памяти этого блока в переменную int* array.

Общая форма new применительно к одномерным массивам выглядит следующим образом:

array_var = new Type[desired_size];
person Android M    schedule 12.07.2015

Начиная с C++11, безопасный для памяти способ сделать это (по-прежнему используя аналогичную конструкцию) — использовать std::unique_ptr:

std::unique_ptr<int[]> array(new int[n]);

Это создает интеллектуальный указатель на блок памяти, достаточно большой для n целых чисел, который автоматически удаляется, когда выходит за пределы области видимости. Эта автоматическая очистка важна, потому что она позволяет избежать ситуации, когда ваш код завершает работу раньше времени и никогда не достигает вашего оператора delete [] array;.

Другой (вероятно, предпочтительный) вариант — использовать std::vector, если вам нужен массив возможность динамического изменения размера. Это хорошо, когда вам нужно неизвестное количество места, но у него есть некоторые недостатки (непостоянное время добавления/удаления элемента). Вы можете создать массив и добавить в него элементы, например:

std::vector<int> array;
array.push_back(1);  // adds 1 to end of array
array.push_back(2);  // adds 2 to end of array
// array now contains elements [1, 2]
person Engineero    schedule 31.10.2017