Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 153, средняя оценка - 4.65
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
#1

realloc и вызов конструктора - C++

20.05.2011, 13:52. Просмотров 18634. Ответов 35
Метки нет (Все метки)

здраствуйте! мне препод сказал, что можно выделить память оператором new, а потом довыделить её с помощью realloc и каким-то образом вызвать конструкторы для новой памяти(ну или это я так его понял). Как это можно сделать?

задание вобще такое:
Во всех вариантах необходимо первоначально создать шаблон класса для работы с массивом произвольного типа данных. Шаблон должен включать:
указатель, хранящий адрес размещения массива в динамической памяти;
целочисленную переменную, показывающую количество занятых элементов массива;
конструктор без параметров, создающий динамический массив заданного типа, с нулевым количеством занятых элементов;
конструктор копирования;
очистку массива;
метод «обработки массива»;
деструктор.
Далее на основе данного шаблона создать класс для работы со строкой символов, специализировав метод «обработки массива» для вашей конкретной задачи.
я хотел класс allocator использовать, но нельзя((. Пока на примете только один вариант - выделять с помощью new и как только память заполниться выделять участок в два раза крупнее копировать старые данные и подчищать за ними. Есть ещё варианты?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.05.2011, 13:52     realloc и вызов конструктора
Посмотрите здесь:

вызов конструктора - C++
Здарова! Есть допустим класс: class Str { Str(); Str(Str&); Str(char*); };

вызов конструктора - C++
Почему при повторном вызове конструктора выбивает ошибку ?Вот здесь ObjX(INUSE); no match for call to `(aClass) (int&)' #include...

Вызов конструктора - C++
void main() { std::string stemporary; int itemporary; float ftemporary; float fftemporary; ECM *pECM; for (int i=0;i<4;i++) ...

Вызов базового конструктора - C++
Такая вот ситуация. Думаю, проблема в объявлении и инициализации массива m. Я бы инициализировал уже в конструкторе, но сначала вызовет...

Вызов конструктора классf! - C++
Всем привет! Вот есть конструктор. SampleTable::SampleTable(const sp<DataSource> &source) : mDataSource(source), ...

Неоднозначный вызов конструктора - C++
class Verylong{ public: Verylong (long x = 0) { enter(x);} Verylong (const Verylong& vrl) : _sign(vrl._sign),...

Вызов конструктора с аргументами - C++
есть класс приложения test_proj в интерфейсе класса в файле test_proj.h создается объект класса Settings. class test_proj { ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
20.05.2011, 13:55     realloc и вызов конструктора #2
pito211, Ага. Можно. А еще стрелять себе в голову тоже не запрещается... Это я на тему new и realloc. realloc не реагирует на конструкторы. Да плюс к тому new выделяет свободную память, а realloc/malloc/calloc выделяют память в куче.
oxotnik
1589 / 1066 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
20.05.2011, 14:09     realloc и вызов конструктора #3
Цитата Сообщение от ForEveR Посмотреть сообщение
Да плюс к тому new выделяет свободную память, а realloc/malloc/calloc выделяют память в куче.
Как это понять?
new изнутри это тот же malloc плюс вызов конструктора
Evg
Эксперт CАвтор FAQ
17549 / 5787 / 370
Регистрация: 30.03.2009
Сообщений: 15,938
Записей в блоге: 26
20.05.2011, 14:27     realloc и вызов конструктора #4
Цитата Сообщение от pito211 Посмотреть сообщение
мне препод сказал, что можно выделить память оператором new, а потом довыделить её с помощью realloc
Нельзя вперемешку использовать new/delete и malloc/realloc/free. Точнее можно, но с непредсказуемыми последствиями. В Си++ нет встроенной конструкции для перевыделения памяти, а потому такое делается через malloc/realloc. Если препод бестолковый из разряда "у меня работает, значит можно", то сделай new/realloc, но для себя надо понимать, что это интерфейсы разных уровней, которые в общем случае не следует перемешивать

Добавлено через 2 минуты
Цитата Сообщение от oxotnik Посмотреть сообщение
new изнутри это тот же malloc плюс вызов конструктора
На самом деле вызов конструктора - это снаружи new, а не изнутри (т.е. вызов конструктора ставит компилятор, а не реализация оператора new). По поводу того, что "это тот же malloc" - это постфактум в реализациях. Но, как мне кажется, никто не гарантирует, что new это в чистом виде обёртка вокруг malloc'а и что там никаких дополнительных действий не делается
oxotnik
1589 / 1066 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
20.05.2011, 14:41     realloc и вызов конструктора #5
Цитата Сообщение от Evg Посмотреть сообщение
Если препод бестолковый из разряда "у меня работает, значит можно"
Препод как раз толковый. Думаю тут задача стоит изучить "изнутри" оператор new как он работает.
А по теме: для своего класса надо переопределить new.

Добавлено через 12 минут
Цитата Сообщение от Evg Посмотреть сообщение
На самом деле вызов конструктора - это снаружи new
да с вызовом конструктора внутри погорячился... ибо на стеке нет никакого new но конструктор вызывается, следовательно new тут не причем

Цитата Сообщение от Evg Посмотреть сообщение
что new это в чистом виде обёртка вокруг malloc'а и что там никаких дополнительных действий не делается
ну еще проверки и вызов исключения если нехватает памяти:
Код
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)
                if (_callnewh(size) == 0)
                {       // report no memory
                static const std::bad_alloc nomem;
                _RAISE(nomem);
                }

        return (p);
        }
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
20.05.2011, 15:00     realloc и вызов конструктора #6
oxotnik, Ну одна из реализаций. Кто сказал что она единственная?

Добавлено через 4 минуты
Тем более что реализовать что-то вроде realloc средствами С++ ну вообще не проблема. Правда он будет не оптимизированный да и вообще, но все же.
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
20.05.2011, 15:16  [ТС]     realloc и вызов конструктора #7
вы уже чё то не то обсуждаете

лучше расскажите как
Цитата Сообщение от ForEveR Посмотреть сообщение
[b]
реализовать что-то вроде realloc средствами С++
без кода, в общих чертах, если не затруднит
Evg
Эксперт CАвтор FAQ
17549 / 5787 / 370
Регистрация: 30.03.2009
Сообщений: 15,938
Записей в блоге: 26
20.05.2011, 15:23     realloc и вызов конструктора #8
Цитата Сообщение от oxotnik Посмотреть сообщение
Препод как раз толковый. Думаю тут задача стоит изучить "изнутри" оператор new как он работает.
А по теме: для своего класса надо переопределить new.
В первом посте написано: "препод сказал, что можно выделить память оператором new, а потом довыделить её с помощью realloc", а в задании про переопределение оператора new ничегоне сказано. Так что хз что тут: либо препод неправильный, либо автор слова препода исковеркал

Цитата Сообщение от oxotnik Посмотреть сообщение
ну еще проверки и вызов исключения если нехватает памяти
Проверки фиг с ними. Я имел в виду то, что new по аналогии с malloc'ом ожет выделять чуть больше памяти, чтобы хранить воспомогательную информацию и при этом возвращать немного не то, что вернул malloc. В этом отношении при комбинации new/realloc можно конкретно накосячить

Цитата Сообщение от ForEveR Посмотреть сообщение
Тем более что реализовать что-то вроде realloc средствами С++ ну вообще не проблема
В одной из тем обсуждали, что встроенных аналогов realloc'а нет, только всякие контейнеры типа std::vector (которые по сути обёртки над malloc/realloc)
oxotnik
1589 / 1066 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
20.05.2011, 15:30     realloc и вызов конструктора #9
Цитата Сообщение от Evg Посмотреть сообщение
Я имел в виду то, что new по аналогии с malloc'ом ожет выделять чуть больше памяти, чтобы хранить воспомогательную информацию и при этом возвращать немного не то, что вернул malloc. В этом отношении при комбинации new/realloc можно конкретно накосячить
Посмотрел реализацию gcc Студии, борланда, везде практически одно и тоже.
Выделяется память через malloc делаются проверки, и указатель возвращается.
Под какую такую информацию надо резервировать доп. память?
А что тогда sizeof будет показывать?
Evg
Эксперт CАвтор FAQ
17549 / 5787 / 370
Регистрация: 30.03.2009
Сообщений: 15,938
Записей в блоге: 26
20.05.2011, 15:45     realloc и вызов конструктора #10
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от oxotnik Посмотреть сообщение
Под какую такую информацию надо резервировать доп. память?
А что тогда sizeof будет показывать?
glibc'шная реализация malloc'f при каждом обращении выделяет памяти больше, чем нужно. И в дополнительную память кладёт магическое число, чтобы делать контроль внутри realloc'а и free. Схематично что-то типа того:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void*
malloc (long size)
{
  char *p;
 
  /* Функцию, которая по-настоящему выделяет память, условно назвал get_mem.
   * В реальности там всё куда сложнее, я просто хочу пояснить принцип
   * Здесь мы выделили дополнительный фрагмент памяти */
  p = get_mem (sizeof (long) + size);
 
  /* В начало реально выделенной памяти кладём магическое число */
  *((long*)p) = 0xdeadbeef;
 
  /* Наружу отдаём память, лежащую за магическим числом */
  return p + sizeof (long);
}
 
void free (void *ptr)
{
  char *p;
 
  /* Наружу мы отдавали результат get_mem со сдвигом. Теперь вернём значение
   * обратно, получив таким образом то, что реально выдал get_mem */
  p = ptr - sizeof (long);
 
  if (*((long*)p) != 0xdeadbeef)
  {
    /* АХТУНГ! Магическое число не совпадает. Вероятнее всего в free подали
     * совсем не то, что вернул malloc */
  }
 
  /* Название функции free_mem условное */
  free_mem (p);
}
Пи таком построении всё читерство с магическими числами сосредоточено внутри интерфейсов malloc и free и для пользователя оно всё прозрачно. Т.е. пользовтатель получил указатель, который вернул malloc, а затем отдал этот указатель в free. То, что это не есть результат настоящего выделения памяти, а результат со сдвигом, снаружи никак не проявляется.

Ровно таким же образом могут быть реализованы операторы new и delete. Т.е. new внутри себя использует malloc, но наружу может отдать немного не то, что вернул malloc

Пример, как это работает в glibc под linux'ом:

C
1
2
3
4
5
6
7
8
9
10
11
#include <stdlib.h>
 
int main (void)
{
  int *p;
  
  p = malloc (100);
  /* Некорректный вызов free */
  free (p + 10);
  return 0;
}
На исполнении видим, что сработал Ахтунг

Код
$ gcc t.c
$ ./a.out
*** glibc detected *** ./a.out: free(): invalid pointer: 0x0804b030 ***
Aborted
oxotnik
1589 / 1066 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
20.05.2011, 15:55     realloc и вызов конструктора #11
Evg, а где тогда хранится размер выделяемой памяти, что бы free(*p) правильно сработал?
Evg
Эксперт CАвтор FAQ
17549 / 5787 / 370
Регистрация: 30.03.2009
Сообщений: 15,938
Записей в блоге: 26
20.05.2011, 16:01     realloc и вызов конструктора #12
Цитата Сообщение от oxotnik Посмотреть сообщение
Evg, а где тогда хранится размер выделяемой памяти, что бы free(*p) правильно сработал?
Например, там же, где и магическое число. Это всё зависит от реализации malloc'а. Реально malloc внутри себя выделяет память с точностью до страницы (чтобы при куче маленьких выделений памяти поменьше обращаться к системе). Там ещё целая куча всяких наноалгоритмов

Вот, например, одна из реализаций malloc'а: тыц

Добавлено через 35 секунд
Цитата Сообщение от oxotnik Посмотреть сообщение
А что тогда sizeof будет показывать?
sizeof от чего?
oxotnik
1589 / 1066 / 33
Регистрация: 21.08.2008
Сообщений: 4,545
Записей в блоге: 1
20.05.2011, 16:09     realloc и вызов конструктора #13
Цитата Сообщение от Evg Посмотреть сообщение
sizeof от чего?
вопрос снимается...
ЗЫ: помогли называется пацану... (ТС который)
pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
20.05.2011, 16:15  [ТС]     realloc и вызов конструктора #14
спасибо всем за развёрнутый ответ
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.05.2011, 16:24     realloc и вызов конструктора
Еще ссылки по теме:

Неправильный вызов конструктора - C++
Доброго времени суток. Возникла такая проблема. Есть такой конструктор House(string s){ int n; string a; for (int i=1;...

Вызов конструктора копий - C++
Всех приветствую! Имеется следующий простенький код: #include &lt;iostream&gt; using namespace std; class Object { ...

Вызов конструктора класса - C++
есть класс Set, и в нем есть конструктор, как с этого конструктора мне массивы перенести в метод другого класса так что бы над ними можно...

Повторный вызов конструктора?! - C++
Мой небольшой класс class CString { private: char* str; int len; int real_size; public: CString() : len(0),...

Вызов конструктора копии - C++
Не вызывается конструктор копии из производного класса #include &lt;iostream&gt; using namespace std; class A { int x; public: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 320
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
20.05.2011, 16:24     realloc и вызов конструктора #15
pito211, Да элементарно. Подход как у вектора.
Используем себе массив - нужно больше - вызываем специальную самописную функцию, перераспределяющую память, путем создания нового указателя (с большим размером выделенной памяти) и копирования туда элементов, удалением старого указателя и присваиванием старому указателю адрес нового, изменение переменной размера для старого.
Ну и собственно-то все.
Yandex
Объявления
20.05.2011, 16:24     realloc и вызов конструктора
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru