Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
1

Оболочка для new с отслеживанием количества выделенной памяти

10.02.2015, 15:45. Просмотров 993. Ответов 15
Метки нет (Все метки)

Здравствуйте, раньше была функция оболочка для malloc()

C
1
2
3
4
5
6
7
8
9
10
11
12
void *_malloc(dword lSize)
{
 
  void *pnt;
  pnt=malloc(lSize);
    if(pnt==NULL)
    {
      /*тут делали какие-то действия и возвращали NULL*/
      return NULL;
    }
  return pnt;
}
Как бы сделать что-то подобное для new

основные вопросы:

1. Возвращаемое значение (ну тут я так понимаю void*);
2. Параметр который я буду передавать в __new(???);

C++
1
2
3
4
5
6
7
8
9
10
11
/*хочу что-то такое...*/
 
void* __new(/*какой-то параметр*/)
{
  try{
    void* ptr = new /*какой-то параметр*/();
  }
  catch(){
    /*обработка исключения*/
  }
}
Если есть идеи, заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2015, 15:45
Ответы с готовыми решениями:

Выделение и удаление памяти, выделенной для динамической строки
Данная функция производит ввод и собственно контроль ввода (размер массива от 1...

Удаление выделенной памяти
#include <iostream> using namespace std; int main() { int...

Освобождение выделенной памяти
Здравствуйте! Есть структура, выглядит, например, так: struct some_structure...

Удаление выделенной памяти
есть такой класс: выделяю память под element *ptemp = new element; и iris...

Корректно ли освобождение выделенной памяти?
Извиняюсь, если такой вопрос уже звучал. Допустим есть такой кусок кода: ...

15
Тамика
Котовчанин
921 / 465 / 196
Регистрация: 16.02.2010
Сообщений: 3,284
Записей в блоге: 28
10.02.2015, 15:49 2
Sherbakov_au, http://en.cppreference.com/w/cpp/memory/new/operator_new
Здесь всё уже описано.
0
DrOffset
8928 / 4809 / 1176
Регистрация: 30.01.2014
Сообщений: 7,847
10.02.2015, 15:50 3
Sherbakov_au, можно перегрузить операторы new\delete.
Вот примеры и документация.
0
Тамика
Котовчанин
921 / 465 / 196
Регистрация: 16.02.2010
Сообщений: 3,284
Записей в блоге: 28
10.02.2015, 15:50 4
Цитата Сообщение от Sherbakov_au Посмотреть сообщение
__new
начинать имя с двух нижних подчеркиваний чревато стандартом.
1
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
10.02.2015, 16:12  [ТС] 5
Цитата Сообщение от Тамика Посмотреть сообщение
Здесь всё уже описано.
С этим все понятно... я не понимаю как потом запустить конструктор и вернуть ссылку на объект...

Цитата Сообщение от Тамика Посмотреть сообщение
начинать имя с двух нижних подчеркиваний чревато стандартом.
да, согласен. Это было к примеру.
0
DrOffset
8928 / 4809 / 1176
Регистрация: 30.01.2014
Сообщений: 7,847
10.02.2015, 17:52 6
Лучший ответ Сообщение было отмечено Sherbakov_au как решение

Решение

Цитата Сообщение от Sherbakov_au Посмотреть сообщение
С этим все понятно... я не понимаю как потом запустить конструктор и вернуть ссылку на объект...
Оператор new предназначен только для выделения памяти. Никакие конструкторы из него вызывать не надо.

Т.е.
C++
1
2
3
4
5
6
7
8
void* operator new(std::size_t sz) {
    // тут делаешь то, что ты хотел сделать с размером.
    return ::operator new(sz);
}
void operator delete(void* ptr) noexcept
{
    ::operator delete(ptr);
}
Конструктор вызовется потом, при использовании new expression, тебе в этот процесс вмешиваться не нужно.
1
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
11.02.2015, 09:23  [ТС] 7
Цитата Сообщение от DrOffset Посмотреть сообщение
Оператор new предназначен только для выделения памяти. Никакие конструкторы из него вызывать не надо.
Понял, спасибо. Надо перегрузить просто его. Только не понял где обработать исключение, если памяти не хватает.
Я думал это делается так:
C++
1
2
3
4
5
6
try{
  type* name = new type(par0,par1,par2);
}
catch(){
  /*тут обработка исключений*/
}
Можно эту обработку засунуть в перегруженный new?
0
Croessmah
++Ͻ
14743 / 8424 / 1598
Регистрация: 27.09.2012
Сообщений: 20,719
Записей в блоге: 2
Завершенные тесты: 1
11.02.2015, 09:27 8
Цитата Сообщение от Sherbakov_au Посмотреть сообщение
Можно эту обработку засунуть в перегруженный new?
у Вас будет свой operator new, хоть показ картинок 18+ там делайте - это Ваше решение.
Только вот как Вы будете сообщать об ошибке вызывающему коду?
Возвратом нуля? Тогда лучше перегрузить и другие версии оператора, иначе чревато головной болью.
0
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
11.02.2015, 10:02  [ТС] 9
Что-то не пошло... А как не перегрузить, а заменить стандартные new и delete. Перегружать надо в каждом классе?
0
ForEveR
В астрале
Эксперт С++
7997 / 4755 / 652
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
11.02.2015, 10:56 10
Sherbakov_au, Нет, можно перегрузить глобальный.

Добавлено через 16 минут
Проблемы только с placement версиями, стандартную версию глобально не переопределить. Все перегрузки можно узреть тут и тут

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
#include <cstdlib>
 
void* allocate(size_t count)
{
   void* ptr = malloc(count);
   std::cout << "allocated " << count << " bytes on " << ptr << std::endl;
   return ptr;
}
 
void deallocate(void* ptr)
{
   std::cout << "deallocate " << ptr << std::endl;
   free(ptr);
}
 
void* operator new(size_t count)
{
   return allocate(count);
}
 
void* operator new(size_t count, const std::nothrow_t&)
{
   return allocate(count);
}
 
void* operator new[](size_t count)
{
   return allocate(count);
}
 
void* operator new[](size_t count, const std::nothrow_t&)
{
   return allocate(count);
}
 
void operator delete(void* ptr)
{
   deallocate(ptr);
}
 
void operator delete(void* ptr, const std::nothrow_t&)
{
   deallocate(ptr);
}
 
void operator delete[](void* ptr)
{
   deallocate(ptr);
}
 
void operator delete[](void* ptr, const std::nothrow_t&)
{
   deallocate(ptr);
}
 
int main()
{
   int* v = new int;
   delete v;
   v = new int[10];
   delete[] v;
   v = new (std::nothrow) int;
   delete v;
   v = new (std::nothrow) int[10];
   delete[] v;
}
1
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
11.02.2015, 11:14  [ТС] 11
Цитата Сообщение от DrOffset Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
void* operator new(std::size_t sz) {
* * // тут делаешь то, что ты хотел сделать с размером.
* * return ::operator new(sz);
}
void operator delete(void* ptr) noexcept
{
* * ::operator delete(ptr);
}
Сделал так. Мне выдал ошибки:

Error[Pe337]: linkage specification is incompatible Z:\Work_Proj\_Modul\source\Main.cpp 8 with previous "operator new" (declared at line 55 of "Z:\Work_Programm\IAR Systems\IAR_6.50.3\arm\inc\cpp\new")

и аналогичную с operator delete

Добавлено через 11 минут
Аналогичная ошибка и в этих случаях. Чего-то не понимаю что нужно сделать, чтобы перегрузить без проблем
0
ForEveR
В астрале
Эксперт С++
7997 / 4755 / 652
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
11.02.2015, 13:20 12
Sherbakov_au, Посмотрите какая декларация у operator new в header файле new.
1
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
11.02.2015, 14:25  [ТС] 13
C++
1
2
3
4
5
6
7
8
9
10
11
void *operator new(_CSTD size_t)
  _THROWS(_XSTD bad_alloc);       // allocate or throw exception
 
// Declare a nothrow new
void *operator new(_CSTD size_t, const _STD nothrow_t&)
  _THROW0();      // allocate or return null pointer
 
inline void *operator new(_CSTD size_t, void *_Where) _THROW0()
{       // construct with placement at _Where
  return (_Where);
}
В ошибке указывает на первую форму.

Добавлено через 52 минуты
Вроде заработало вот так (не знаю на сколько это правильно), но все равно выдает предупреждение:

Warning[Pe541]: omission of exception specification is incompatible with previous function "operator new(std::size_t)" (declared at line 55 of "Z:\ Z:\Work_Proj\_Modul\source\Main.c 15

не знаю как его убрать.

C++
1
2
3
4
5
extern "C++" void *operator new(size_t size)
{  /*предупреждение указывает на эту скобку*/
    void* ptr = malloc(size);
    return ptr;
}
Если знаете как от него избавится, помогите пожалуйста.
0
ForEveR
В астрале
Эксперт С++
7997 / 4755 / 652
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
11.02.2015, 14:51 14
Лучший ответ Сообщение было отмечено Sherbakov_au как решение

Решение

Sherbakov_au, Добавить exception-specification.
C++
1
2
void* operator new(size_t count) throw(std::bad_alloc);
void* operator new(size_t count, const std::nothrow_t&) throw();
И т.д.
1
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
11.02.2015, 15:16  [ТС] 15
Да, все получилось, спасибо огромное.

C++
1
2
3
4
5
6
7
8
9
10
11
extern "C++" void *operator new(size_t size)throw(std::bad_alloc)
{
    void* ptr = malloc(size);
    if(ptr==NULL)return NULL;
 
    return ptr;
}
extern "C++" void operator delete(void *ptr)throw()
{
    free(ptr);
}
0
Sherbakov_au
1 / 1 / 1
Регистрация: 11.12.2014
Сообщений: 15
12.02.2015, 15:20  [ТС] 16
Еще вопрос появился, нужно перегрузить все формы new и delete, или хватит только основных?
0
12.02.2015, 15:20
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.02.2015, 15:20

Освобождение памяти, выделенной через new
Я прочитал, что память динамически для строки, можно выделить к примеру узнать...

Массив: Освобождение выделенной памяти
Сказали переделать код, нужно что бы память освобождалась не в отдельной...

Мусор в памяти, выделенной динамически
Есть код, выполняет разархивацию файла, закодированного LZ77. Вот его основная...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

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