Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как распределяет память конструктор копирования, Где и когда это происходит 
:(
    Опции темы
AlanG
Дата 12.6.2006, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 11.5.2006
Где: РашЫн ФидирейшЫн

Репутация: нет
Всего: нет



Всем доброго времени суток smile 
Меня интересует как происходит распределения памяти при создании копии объекта.
Имеем класс который содержит конструктор копирования. Как извесно, он распределяет НОВУЮ память для созданного объекта. Вот только не понятно ГДЕ и КАК он это делае? И еще, если в классе имеем оператор new который тоже распрелеляет память, какая тогда будет связь между памятью от конструктора непосредственно и памятью от оператора new ?

Пример:

Код

#include<iostream>
#include<new>
#include<cstdlib>
using mamespace std;

//***///***

calss array {
 int *p;
 int size;

 //Конструктор  
 array(int sz){
   try{ p=new int[sz]; 
 } catch(bad_alloc xa){
   cout<< "Pisez"\n;
   exit(EXIT_FAILURE); 
 }
  size=sz; //Получить значение от созданного объекта (a) 

 //Конструктор копирования
 array (const array &a){
   try{ p=new int[a.size]; 
      }catch(bad_alloc xa){
   cout<< "Pisez"\n;
   exit(EXIT_FAILURE); 
      } 
    }
 };

void main(){
 array a(11); //Создается объект
                    //Вызывается констрктор   
 array a2_copia(a); //Вызов конструктора копирования 

}


 
PM MAIL   Вверх
Earnest
Дата 12.6.2006, 12:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(AlanG @  12.6.2006,  13:20 Найти цитируемый пост)
 Как извесно, он распределяет НОВУЮ память для созданного объекта

Не "как известно", а "как напишешь".
Конструкторы не распределяют память. 
Они инициализируют объект в той памяти, которую им дали. 
В твоем примере оба объекта создаются на стеке.
Если ты в своей реализации конструктора выделяешь память оператором new, то это частный случай. Память выделяется всегда в куче (если ты используешь стандартный new). Никакой связи с тем, какую память получил конструктор, нет. Т.е. как бы ни был создан объект array (как глобальная переменная, как автоматический объект или динамически, через new) - внутренний new будет выделять память одинаково.
 


--------------------
...
PM   Вверх
AlanG
Дата 12.6.2006, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 11.5.2006
Где: РашЫн ФидирейшЫн

Репутация: нет
Всего: нет



Цитата

Конструкторы не распределяют память. 

Я наверное НЕдописал кое что smile 
Конструкторы копирования, как раз таки распределяют память, для этого они и предусмотрены. Если конструктор копирования ЯВНО не реализован в програме, используется конструктор по умоляанию, но с ним пробдлема, при вызове деструктора, удаляется память каждого из созданных объектов (естественно из этого же класса). Когда создается новый объект (точнее копия объекта а), в данном случае он создается при создании нового объекта a2_copia. (еще может создаватся при вызове функций с передачей объекта). Копия создается именно в тот момент, когда передается параметр в виде объекта. Собствено вопрос: ГДЕ и КАК распределяется память для ЭТОЙ копии (копии объекта а)?

Добавлено @ 12:42 
Про new я зря упомянул, только запутал..... 
PM MAIL   Вверх
Daevaorn
Дата 12.6.2006, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(AlanG @  12.6.2006,  13:41 Найти цитируемый пост)
Конструкторы копирования, как раз таки распределяют память, для этого они и предусмотрены

Ложь!
Код

array (const array &a)

Сама сигнатура его говорит о том, что он работает уже с выделенной памятью под объекты( что уже сказала Earnest ). 
Цитата(AlanG @  12.6.2006,  13:41 Найти цитируемый пост)
 ГДЕ и КАК распределяется память для ЭТОЙ копии (копии объекта а)?

На стеке, ты сам это написал:
Код

array a2_copia(a); 

 
PM MAIL WWW   Вверх
MAKCim
Дата 12.6.2006, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



когда компилятор встречает вызов конструктора копирования для объекта, который будет размещен в стеке
то скорее всего просто уменьшается указатель стека на sizeof(<структура, представляющая данные объекта класса>) ,байт и call-ом вызывается процедура, соответствующая конструктору копирования (или сгенерированному КК) и туда передается указатель на первый байт данных объекта (текущий (измененный) указатель стека). Собственно эта процедура и инициализирует поля объекта (то есть не занимается выделением памяти а работает уже с существующими адресами)
  

Это сообщение отредактировал(а) MAKCim - 12.6.2006, 12:54


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
AlanG
Дата 12.6.2006, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 11.5.2006
Где: РашЫн ФидирейшЫн

Репутация: нет
Всего: нет



Цитата

Сама сигнатура его говорит о том, что он работает уже с выделенной памятью под объекты( что уже сказала Earnest ).

Тогда я наверное чего то недопонял... Хорошо, а что происходит когда я передаю объект в качестве параметра, другой функции?
Код

void main(){
 array a(11); //Создается объект
                     //Вызывается констрктор   
 func1(a);  //Передача объекта (передается копия, для которой, конструктор  распределяет НОВУЮ память)
}

 func1(array a1) {
 cout<<a1.size;
 }
 
PM MAIL   Вверх
Earnest
Дата 12.6.2006, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(AlanG @  12.6.2006,  13:41 Найти цитируемый пост)
при вызове деструктора, удаляется память каждого из созданных объектов 

Это тоже не так. Распределение\освобождение памяти и конструирование\разрушение объекта - это два разных процесса, никак не связанных. Т.е. только на вид они связаны.
Выделение\освобождение памяти - это new\delete. При вызове деструктора память не удаляется. Когда ты пишешь MyClass* pa = new MyClass(аргументы); то сначала выделяется память (оператором new), а потом эта память передается конструктору для инициализации. Если объект размещается на стеке, то память не выделяется, а просто, как написал MAKCim, текущий указатель стека смещается на размер объекта, а предыдущий передается конструктору для инициализации (что-то типа placement new). Собственно, сам механизм placement new - это способ вызвать конструктор в нужной области памяти.
Инициализация - это, грубо говоря, присваивание начальных значений данным и, в случае полиморфных классов, присваивание нужного адреса таблице виртуальных ф-й (возможно не одной). Деструктор ... да, в общем, может ничего не делать. Разве что подменяет \ очищает адрес vtable...  


--------------------
...
PM   Вверх
Daevaorn
Дата 12.6.2006, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(AlanG @  12.6.2006,  14:04 Найти цитируемый пост)
func1(array a1)

В данном случае объект-параметр a1 будет создан на стеке, т.к. передается по значению. 
PM MAIL WWW   Вверх
MAKCim
Дата 12.6.2006, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Хорошо, а что происходит когда я передаю объект в качестве параметра, другой функции?

1. Изменение указателя стека на размер объекта
2. Передача нужного адреса через стек в процедуру которая соответствует конструктору копий
3. Инициализация полей в этой процедуре
4. Вызов нужной функции (при этом объект будет находится по текущему указаателю стека + 4 байта (на 32 разрядных платформах)) 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0861 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.