2016-04-28 7 views
4

Я изучаю C++, и я знаю, что «новое» ключевое слово используется для выделения адреса в памяти указателю. И я думаю, что при использовании 'nullptr' инициализирует указатель, который указывает на ничего. Это верно? Пример для справки:C++: Разница между установкой указателя на nullptr и инициализацией его как новой переменной типа

//using nullptr 
int *x = nullptr; //this is just a pointer that points to nothing and 
        //will need to be initialized with an address before it 
        //it can be used. Correct? 

//using new 
int *x = new int; //this is basically giving x an address in memory. Will the 
        //address have some residual value stored in it or will 
        //it contain zero? 

Когда вы будете использовать один над другим? Является ли новое, используемое только для динамического распределения памяти, или для него существуют другие приложения? Зачем вам инициализировать указатель на nullptr, если вы можете просто объявить его, а затем инициализировать его позже?

Спасибо за помощь!

ответ

0

Ваше понимание неверное. nullptr - хорошее значение для инициализации, чтобы указать, что указатель не указывает на память. Кроме того, операция delete на nullptr является безопасной, в то время как delete на произвольные значения (как правило, это случай, когда вы не инициализируете указатель) может вызвать сбои сегментации.

Если вы хотите инициализировать память до нуля, используйте new int(). В противном случае память может иметь остаточные данные.

1

int *x = nullptr; Вы в порядке. Значение x составляет nullptr и nullptr ... Э-э ... Давайте спросим экспертов: What exactly is nullptr? В любом случае это не совсем ничего. Это просто гарантированное безопасное место для парковки до тех пор, пока указатель не будет использоваться для лучшего использования.

int *x = new int Чтение значения, указанного в x, *x будет Undefined Behaviour. Вероятно, вы получите остаточную стоимость, но кто может сказать наверняка?

int *x = new int(); Чтение *x получите 0.

int *x = new int(1000000); Чтение *x получите 1000000.

Если у вас нет ничего, чтобы указать на, использовать nullptr в качестве заполнителя. Не выделяйте хранилище, чтобы дать указателю что-то, на что он указывает. Это потраченная впустую память, это потраченное время на распределение и освобождение, и это потенциальная утечка памяти, если вы забудете ее delete. nullptr безопасен. Вы можете проверить для nullptr и принимать решения о качестве информации, на которую он указывает. Вы можете deletenullptr, не опасаясь гадости, если не уверены, используется ли указатель или нет.

+0

Первый не будет UB. 'x' будет просто указывать на неинициализированное значение. Использование этого неинициализированного значения будет UB. –

+0

Спасибо. Очистка формулировки. – user4581301

+0

Педантичность: чтение '* x' - неопределенное поведение. Чтение 'x' в порядке (хотя для значения необработанного указателя мало пользы). – ShadowRanger

1
int *x = nullptr; 

// some code here that might under some condition 
// lead to an actual object address being stored in x 

if (x) 
{ 
    // do some stuff here which is only performed if 
    // x doesn't contain a nullptr value anymore 
} 

Это не тот случай, когда указатели служат только для целей, когда они фактически указывают на объект. Значение nullpointer абсолютно обычное. Вы можете проверить, является ли указатель nullptr или нет, и для проверки требуется, чтобы указатель был инициализирован.

Его не нужно инициализировать с использованием фактического адреса.

Вы хотите инициализировать указатель точно так же, как и любой другой фундаментальный тип, который имеет неопределенное значение, если не инициализирован: чтобы сразу же получить его действительное значение, не имея в виду, что вам все равно нужно его инициализировать.

Переменная указателя, как и любая другая фундаментальная переменная.

  • Он находится в стеке, имеющей sizeof(int*) байт памяти для хранения адреса типа int
  • Это не будет инициализирован (неопределенных), если нет Initializer

Когда бы вы использовать один над другим?

Первый (nullptr): Если указатель может на самом деле оставаться nullptr. Второй (new int): Когда вы знаете, что вам действительно понадобится выделенное целое число.

PS: Исходные указатели на самом деле должны быть редкими в настоящее время (по уважительным причинам).

0

И я думаю, что при использовании nullptr инициализирует указатель, который указывает на ничего. Это верно? Когда вы будете использовать один над другим? Зачем вам инициализировать указатель на nullptr, если вы можете просто объявить его, а затем инициализировать его позже?

Да. Важно помнить, что как только вы выделяете память указателю, вам нужно управлять им. Таким образом, nullptr является значением дозорного, что означает, что указатель не указывает на что-либо.

Новинка используется только для распределения динамической памяти или есть другие приложения для нее?

Это только функция new. Вы можете специализироваться на этом поведении с размещением new, но вы по-прежнему выделяете память.

1

Да, вы, как правило, правы в своем описании того, что делают эти два назначения.

Что касается вашего вопроса о том, почему вы должны инициализировать указатель на NULL, это значит, что ваш код может позже протестировать против NULL. Обычная парадигма заключается в том, что если указатель NULL, то вы знаете, что он не инициализирован и не указывает ни на что. Если это не NULL, то предположительно это указывает на действительный объект, и вы можете его использовать. Хотя эта парадигма означает, что вам нужно убедиться, что указатель вернулся к NULL, когда объект, на который оно указывает, удаляется или иным образом отображается недействительным. Вы можете посмотреть, как работают умные указатели, а не обычные «тупые» указатели.

2

Ваше понимание new int и int *x = new int; неверен (или, по крайней мере, так, как вы это указали неправильно).

new int выделяет некоторую память. Он не «выделяет память указателю», он просто выделяет память. Он поставляет указатель на эту память, которая раньше не существовала.

int *x; также выделяет память для переменной x. x - это переменная, значение которой является адресом другого объекта. (в отличие от других типов переменных, значение которых может быть числом или строкой, например).

int *x = nullptr; Средство x содержит специальное значение, называемое нулевым указателем, которое не указывает на какой-либо другой объект.

int *x = new int означает, что x содержит адрес части памяти, выделенной new int. Таким образом, в этой строке задействованы два распределения: x и неназванная память, выделенная new.

В последнем случае вы можете выводить адрес каждого из этих распределений отдельно, например .:

cout << &x << ',' << x << '\n';