Void main()
{
int number;
int *pNumber = number;
delete pNumber;// ошибка - память для *pNumber не была выделена при помощи new.
}
Общие вопросы и ЧаВо
Вопрос: Почему я получаю ошибки "symbol undefined" при использовании new и delete?
Ответ: вероятнее всего, это происходит потому, что ваш исходный код интерпретируется компилятором как написанный на языке C. Операторы new и delete являются новыми возможностями языка C++. Ситуацию обычно можно исправить, указав для исходных файлов расширение *.cpp вместо *.c
Вопрос: в чем разница между new и malloc?
Ответ: Оператор new существует только в языке C++ и является стандартным (за исключением особых функций в Windows) способом выделения памяти. Вы не должны использовать malloc в C++, разве что в случае крайней необходимости. Поскольку malloc не был разработан для объектно-ориентированных возможностей языка C++, его использование для выделения памяти для классов приведет к тому что конструктор класса вызван не будет, как пример того какие проблемы могут возникнуть. В результате проблем возникших при использовании malloc и free, а также, потому что они устарели для любого использования (в языке C++) в этой статье они не обсуждаются детально. Я не одобряю использование этих функций, где бы то ни было.
Вопрос: можно ли использовать free и delete вместе?
Ответ: Вы должны освобождать память тем же механизмом, которым вы её выделяли. Например, используйте free только в случае если память выделялась функцией malloc, delete используется только если память выделялась при помощи new, и так далее.
Ссылки
Ссылки определенно находятся вне темы этой статьи. Но поскольку меня очень часто спрашивали о ссылках люди, которые читали эту статью, я опишу их кратко. Ссылки очень схожи с указателями и в большинстве случаем они могут быть использованы как альтернатива указателям. Как вы помните я уже писал что амперсанд (&) читается при объявлении как "адрес переменной ...". В случае присутствия амперсанда в объявлении в том виде, который показан ниже - его следует читать как "ссылка на переменную ...".
int& Number = myOtherNumber;
Number = 25;
Ссылки это те же что и указатель на myOtherNumber, за исключение того что ссылка автоматически разыменовывается. Таким образом, ссылка ведет себя как переменная со значением, а не как переменная с адресом (как указатель). Идентичный по смыслу код, использования указателей показан ниже:
int* pNumber = &myOtherNumber;
*pNumber = 25;
Другое отличие между указателями и ссылками это то, что вы не можете "сбросить" ссылку. Это означает что нельзя изменять значение адреса ссылки после того как она была инициализирована. Например, код ниже выведет "20":
int myFirstNumber = 25;
int mySecondNumber = 20;
int &myReference = myFirstNumber;
myReference = mySecondNumber;
printf("%d", myFristNumber);
При использовании в классе, значение ссылки должно быть установлено в конструкторе следующим образом:
CMyClass::CMyClass(int &variable) : m_MyReferenceInCMyClass(variable)
{
// код конструктора
}
Заключение
Тему указателей сложно освоить с первого раза, так что стоит просмотреть всё заново. Большинство людей не понимает всё с первого прочтения. Вот основные моменты снова:
Указатели это переменные, которые указывают на область памяти. Вы объявляете указатель добавляя звездочку (*) перед именем переменной (int * number).
Вы можете получить адрес переменной, добавив амперсанд (&) перед её именем, например pNumber = &my_number.
Звездочка при объявлении переменной (например, int * number), читается как "адрес памяти который указывается переменной ...".
Амперсанд при объявлении переменной (например, int &number), читается как "адрес переменной ..."
Вы можете выделять память, используя оператор new.
Указатели ДОЛЖНЫ быть того же типа что и переменные на которые вы хотите чтобы они указывали. Например, int *number не будет указывать на MyClass.
Вы можете передавать указатели в функции.
Вы должны удалит память, которая была выделена при помощи оператора delete.
Вы можете получить указатель на массив, который уже существует следующим образом: &array[0];.
Вы должны удалить массив память, для которого была динамически выделена следующим образом: delete[], а не просто delete.
Это не абсолютно полное руководство по работе с указателями. Есть еще много вещей, которые я мог бы раскрыть более детально, таких как указатели на указатели, и тем, которых я не коснулся вообще, например, функциональных указателей, которые слишком сложны для этой статьи. Так же есть вещи, которые используются слишком редко, чтобы сбивать начинающих с толку обилием деталей.
Вот и все! Попробуйте запустить код представленный в этой статье и придумать ещё какие-нибудь свои вариации и примеры.
-------------------------------------------------------------------------------
http://translated.by/you/a-beginner-s-guide-to-pointers/into-ru/trans/
© Andrew Peace
Original (English): A Beginner's Guide to Pointers (http://www.codeproject.com/KB/cpp/pointers.aspx)
Translation: © Mr.ElectroNick, Someone.else, Grigoriy, m0nhawk, Dmitry-Leushin, ventalf, voxpuibr, Axx, dShadow.
License: The Code Project Open License (CPOL)
translated.by crowd