2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: досоздание массива :) С++
Сообщение08.10.2009, 02:04 
Заслуженный участник


09/08/09
3438
С.Петербург
venco в сообщении #249984 писал(а):
Таким образом вы измените функцию, которую вызывает компилятор на первом шаге.

Так мне больше ничего и не надо. Надо только, чтобы new брал память из системной кучи, а delete ее туда возвращал. Естественно, конструктор всегда будет создавать "чистый" массив, но потом я смогу изменить его размер.
Как-то так:
Код:
int *a = new int[10000];
...
a = realloc_ex(a, sizeof(int), 20000);
...
delete [] a;

Или я опять Вас неправильно понял? :)

 Профиль  
                  
 
 Re: досоздание массива :) С++
Сообщение08.10.2009, 03:22 
Заслуженный участник


04/05/09
4582
Это будет работать для примитивных объектов. При этом достаточно воспользоваться уже существующими фунциями malloc/realloc/free.
И не будет работать для объектов с конструкторами/деструкторами.
Код:
int *a = (int*)malloc(sizeof(int)*10000);
...
a = (int*)realloc(a, sizeof(int)*20000);
...
free(a);

 Профиль  
                  
 
 Re: досоздание массива :) С++
Сообщение08.10.2009, 09:47 
Заслуженный участник


09/08/09
3438
С.Петербург
venco в сообщении #249987 писал(а):
И не будет работать для объектов с конструкторами/деструкторами.
Извините, тут я опять не понял. Почему не будет работать для объектов с конструкторами/деструкторами?
Конструктор получает блок памяти, который он должен инициализировать, и его абсолютно не волнует, каким образом этот блок памяти был получен - статически, на стеке, в куче или еще как-нибудь.
Почему стандарные operator new, operator new[], operator delete и operator delete [] работают для всех объектов, а переопределенные не будут работать для объектов с конструкторами/деструкторами?

-- Чт окт 08, 2009 13:13:09 --

venco в сообщении #249987 писал(а):
При этом достаточно воспользоваться уже существующими фунциями malloc/realloc/free.
Стандартный realloc не подходит: он выделяет новый блок памяти и копирует в него содержимое старого, а первоначальная идея была в том, чтобы увеличивать размер блока "по месту".

 Профиль  
                  
 
 Re: досоздание массива :) С++
Сообщение08.10.2009, 20:41 
Заслуженный участник


04/05/09
4582
Maslov в сообщении #250007 писал(а):
venco в сообщении #249987 писал(а):
И не будет работать для объектов с конструкторами/деструкторами.
Извините, тут я опять не понял. Почему не будет работать для объектов с конструкторами/деструкторами?
Конструктор получает блок памяти, который он должен инициализировать, и его абсолютно не волнует, каким образом этот блок памяти был получен - статически, на стеке, в куче или еще как-нибудь.
Почему стандарные operator new, operator new[], operator delete и operator delete [] работают для всех объектов, а переопределенные не будут работать для объектов с конструкторами/деструкторами?
Может быть, вы путаете operator new() и выражение с new?
То, что можно переопределить - operator new() - занимается только выделением памяти и ничего не знает о том для чего эта память предназначена.
Выражение с new вызывает ту последовательность действий, что я привёл выше.
Она включает в себя не только выделение памяти, но и вызовы необходимых конструкторов, которые, в свою очередь, могут создать в куче ещё объекты.
Так вот, если вы попытаетесь сделать что-то типа realloc() с объектами, то даже если память останется той же, компилятор создаст в этой памяти новые объекты, проигнориривав старое содержимое, как и всякий мусор, который может оказаться в памяти, выделенной из куче оператором new(). А вам ведь не это нужно, не так ли?

Maslov в сообщении #250007 писал(а):
venco в сообщении #249987 писал(а):
При этом достаточно воспользоваться уже существующими фунциями malloc/realloc/free.
Стандартный realloc не подходит: он выделяет новый блок памяти и копирует в него содержимое старого, а первоначальная идея была в том, чтобы увеличивать размер блока "по месту".
Стандартный realloc() увеличит размер блока на месте, если есть куда увеличивать. А если нет, то всяко копировать придётся.

 Профиль  
                  
 
 Re: досоздание массива :) С++
Сообщение08.10.2009, 21:18 
Заслуженный участник


09/08/09
3438
С.Петербург
venco в сообщении #250167 писал(а):
Может быть, вы путаете operator new() и выражение с new?
Да нет, не путаю :)
venco в сообщении #250167 писал(а):
Так вот, если вы попытаетесь сделать что-то типа realloc() с объектами, то даже если память останется той же, компилятор создаст в этой памяти новые объекты ...

Идея в следующем:
Во-первых, переопределяется способ выделения памяти не для всех объектов в программе, а только для объектов определенного класса (того самого, для которого надо хранить огромные массивы).
Наша функция "типа realloc" сначала просто увеличивает размер блока памяти "по месту". Компилятор и знать про это ничего не знает, поэтому никаких конструкторов автоматически вызывать не будет.
Затем явно вызываем new для инициализации новых объектов, память под которые была только что добавлена. При этом переписываем new для объектов нашего класса таким образом, чтобы он не выделял новую память, а просто возвращал указатель на соответствующий кусочек внутри нашего блока. Например, можно просто передавать индекс элемента, который надо инициализировать, в вызове new в качестве дополнительного параметра, типа
Код:
new(10) A();

При этом компилятор вызовет конструктор для инициализации этого блока памяти, и все будет нормально.

Конечно, тут есть еще масса моментов, которые надо учесть, типа
- корректная работа со стандартным заголовком объекта (отрицательные смещения, по которым хранится адрес VTBL и, наверное, еще что-то.
- чтобы правильно работал delete [], в "типа realloc" надо корректировать значение поля, содержащего фактический размер массива
- каким-то образом надо резервировать виртуальное адресное пространство, чтобы его хватило на увеличение длины массива
- и т.п.

И еще: все вышеизложенное - просто идея, как это можно сделать. Ни малейшего намерения эту идею реализовывать в жизни у меня нет. Но в принципе, все должно работать :)

 Профиль  
                  
 
 Re: досоздание массива :) С++
Сообщение09.10.2009, 03:42 
Заслуженный участник


26/07/09
1559
Алматы
2Nerazumovskiy
Цитата:
Вобщем такая проблема возникала:
Уак довыделить памяти в в динамическом массиве, если мне вдруг длинны массива не хватило не хватает походу дела(вернее как это сделать нетопорным методом)?

Можно реализовать ваш массив в виде связанного списка. Когда нужно будет увеличить его длину, просто выделяйте память под новый элемент и цепляйте его к основному массиву.

 Профиль  
                  
 
 Re: досоздание массива :) С++
Сообщение16.10.2009, 23:42 


30/09/09
9
Всё можно! это делается достаточно просто.
Создаём void функцию, в которую засылаем исходный массив и его размерность, в этой функции создаём новый массив с количеством требуемых элементов, копируем весь исходный массив в новый,увеличиваем исходную размерность на необходимое количество, и делаем следующую штуку с помошью константной ссылки this:
Код:
delete []this->elem;
this->elem=p;

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

 Профиль  
                  
 
 Re: досоздание массива :) С++
Сообщение17.10.2009, 06:29 
Заслуженный участник


04/05/09
4582
В этой теме Gendolf, похоже, тоже не прочитал, о чём речь.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу Пред.  1, 2

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group