man2D Posted November 7, 2003 Report Share Posted November 7, 2003 Народ, подскажите пожалуйста, зачем нужны указатели! Link to comment Share on other sites More sharing options...
Тролль Posted November 7, 2003 Report Share Posted November 7, 2003 Указатель - это объект, в котором хранится адрес чего-то. У этого объекта есть некоторые свойства, например, он помнит размер блока памяти, адрес которого он хранит. Он знает и другие вещи, например, можно ли изменять содержимое блока памяти, на который он ссылается. Указатель часто используется для работы с массивами, так как к содержимому указателя надо прибавить смещение, чтобы получить адрес нужного элемента массива. Но очень полезен, как посредник, и для работы с другими объектами. Пример использования указателя для работы с динамическим массивом: Создаем указатель на блок памяти, предназначенный для хранения целого, выделяем память для хранения 50-ти целых и помещаем адрес начала этого блока памяти в указатель: int *p; p=new int[50]; Теперь с этим массивом можно работать: p[2]=8; или, что то же самое, *(p+2)=8 (тут мы прибавили к указателю два размера блоков памяти, соответствующих типу указателя, взяли ячейку с этим адресом (операция *) и поместили нее 8 ). Когда этот массив больше не нужен, память можно освободить: delete [] p; Можно создавать и массивы указателей, в том числе динамические, и т.д. Link to comment Share on other sites More sharing options...
Ray Posted November 8, 2003 Report Share Posted November 8, 2003 Кстати, об указателях, а точнее о массивах в С++ Знаю один прикол, не имеющий, правда практического прменения... К ячейке массива мы обращаемся обычно как например p[10]==3 Если написать 10[p]==3 то это тоже будет работать! Связано это то ли с предпроцессором С++ то ли с компиляцией, написание p[10] преобразуется в форму p+10, и поэтому 10[p] будет выглядеть как 10+p то есть тоже верно... Link to comment Share on other sites More sharing options...
Smagl Posted November 8, 2003 Report Share Posted November 8, 2003 Маленькие дополнения. 1. При использовании указателей снимается ограничении на размер массива. Можно задать массив хоть из 10 млрд. элементов. Обычным способом так сделать нельзя. 2. Обращение по адресу работает быстрее, чем просто обращение к элементу массива. Link to comment Share on other sites More sharing options...
man2D Posted November 9, 2003 Author Report Share Posted November 9, 2003 А как создать массив с размерами, которые задаёт юзер? Link to comment Share on other sites More sharing options...
Ray Posted November 9, 2003 Report Share Posted November 9, 2003 Тебе Тролль все прекрасно написал... Создаем указатель на блок памяти, предназначенный для хранения целого, выделяем память для хранения 50-ти целых и помещаем адрес начала этого блока памяти в указатель: int *p; p=new int[50]; На тебе прмерный кусок программы: int size=0; cout << "Enter size of array: "; cin >> size; int *p = new int; for (int i=0;i<size;i++) { p=i+1; cout << p << ' '; } delete [] p; Link to comment Share on other sites More sharing options...
man2D Posted November 9, 2003 Author Report Share Posted November 9, 2003 Огромное спасибо. Наверное, это книжка тупая попалась... Link to comment Share on other sites More sharing options...
Smagl Posted November 9, 2003 Report Share Posted November 9, 2003 Огромное спасибо. Наверное, это книжка тупая попалась... Да, мало хороших книг Вот человек - хорошая книга ;) А форум - целая библиотека хороших книг :D Link to comment Share on other sites More sharing options...
man2D Posted November 10, 2003 Author Report Share Posted November 10, 2003 Smagl Ну да, а есть ведь ещё чаты, аськи и т.п. Так что интернетом можно назвать бесконечное множество книг Link to comment Share on other sites More sharing options...
Alex1010 Posted December 29, 2003 Report Share Posted December 29, 2003 А как создать массив с размерами, которые задаёт юзер? Для этого существуют структуры данных, именуемые связанными списками. Link to comment Share on other sites More sharing options...
Тролль Posted December 29, 2003 Report Share Posted December 29, 2003 Alex1010 Массив и связанный список - разные вещи. В массиве ты получаешь нужный элемент сразу вычислением его положения с помощью индекса, а в связанном списке ты должен пробежаться по всей цепочке элементов, чтобы добраться до нужного. Зато внутрь списка легко включать элементы, как и исключать их из списка, а раздвинуть массив далеко не так легко. Можно моделировать массив связанным списком или связанный список массивом, но в любом из этих случае это будет очень нерационально. Link to comment Share on other sites More sharing options...
Alex1010 Posted December 29, 2003 Report Share Posted December 29, 2003 Совершенно верно! А на вопрос "А как создать массив с размерами, которые задаёт юзер? " Вы как ответите? Link to comment Share on other sites More sharing options...
Тролль Posted December 30, 2003 Report Share Posted December 30, 2003 Alex1010 Сошлюсь на программу, которую написал Ray и поместил в этой же теме несколькими сообщениями выше, она прекрасно показывает создание такого массива на работающем примере. Link to comment Share on other sites More sharing options...
Архимаг Posted September 28, 2009 Report Share Posted September 28, 2009 Возник вопрос касательно указателя и выделения памяти динамически: Известно, что в результате неправильного манипулирования паматью можно получить ее утечку. К примеру: int *p = new int;*p=10;p=new int;*p=15; В чем проблема приведенного кода ? В строке 1 выделяется память для значения int. В строке два, в эту область записывается значение 10. Далее указателю присваивается адрес другой области, в которую записывается число 15. Таким образом, первый участок памяти с числом 10, оказался недоступен. И нельзя ни использовать ни освободить его... Пример взят из Либерти... Идя дальше по книге, наткнулся на такую программу. class Mammal{ public: Mammal():itsAge(1) {cout << "Mammal constructor...\n";} virtual ~Mammal() {cout << "Mammal destructor...\n";} virtual void Speak () const {cout << "Mammal speak!\n";} protected: int itsAge;};class Dog: public Mammal{ public: void Speak()const {cout << "Woof!\n";}};class Cat: public Mammal{ public: void Speak()const {cout << "Meow!\n";}};class Horse: public Mammal{public: void Speak() const {cout << "Winnie!\n";}};int main(){Mammal *theArray[3];Mammal *ptr;int choice, i;for(i=0; i<3; i++) { cout << "(1)dog (2)cat (3)horse: "; cin >> choice; switch(choice) { case 1: ptr = new Dog; break; case 2: ptr = new Cat; break; case 3: ptr = new Horse; break; } theArray[i] = ptr;}for(i=0; i<3; i++) theArray[i]->Speak();return 0;} Если заглянуть в функцию main, в первый цикл, в тело оператора switch, то разве там нельзя наблюдать упомянутую в предыдущем примере утечку ? Цикл содержит 3 итерации, в каждой из которых указателю ptr присваивается адрес новой области, без предварительного освобождения... Или автор делает скидку на скорое завершение программы, т.к. при этом память освободиться автоматически ? Link to comment Share on other sites More sharing options...
Тролль Posted September 28, 2009 Report Share Posted September 28, 2009 Архимаг: for(i=0; i<3; i++) { cout << "(1)dog (2)cat (3)horse: "; cin >> choice; switch(choice) { case 1: ptr = new Dog; break; case 2: ptr = new Cat; break; case 3: ptr = new Horse; break; } theArray = ptr; } ptr действительно присваивается каждый раз адрес новой области, но он тут же передается в theArray = ptr;Все эти области нужны, они становятся содержанием массива theArray, поэтому отдавать обратно отведенную для них память нельзя, ptr тут - просто необязательное передаточное звено для адреса. Link to comment Share on other sites More sharing options...
Архимаг Posted September 28, 2009 Report Share Posted September 28, 2009 Архимаг: ptr действительно присваивается каждый раз адрес новой области, но он тут же передается в theArray = ptr; Все эти области нужны, они становятся содержанием массива theArray, поэтому отдавать обратно отведенную для них память нельзя, ptr тут - просто необязательное передаточное звено для адреса. Т.е. если взять два указателя: int *p1 = new int; int *p2 = p1; Они будут содержать адрес одной и той же области. Если освободить указатель p1: delete p1; то работа с указателем p2 будет невозможно ? Link to comment Share on other sites More sharing options...
Тролль Posted September 28, 2009 Report Share Posted September 28, 2009 (edited) Присвоить ему новый адрес можно. А по старому адресу, на который он ссылается, может уже лежать все, что угодно. Фактически мы освобождаем для любых других применений не указатель p1, а область памяти, на которую он указывал. Адрес в указателе p2 остается прежним, но в квартире по указанному адресу могут быть уже другие жильцы, чаще всего ноли, но это зависит от компилятора. Edited September 28, 2009 by Тролль Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now