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

Динамическое размещение объекта в определённом месте памяти с последующим её освобождением

04.10.2013, 18:39. Просмотров 602. Ответов 14
Метки нет (Все метки)

Доброго времени суток.

В C++ имеется возможность размещать объект по чётко определённому, указанному разработчиком, адресу в памяти. В свете этого у меня возник вопрос об освобождении памяти, использованной таким образом.

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

На вскидку, мне видится три возможных варианта освобождения памяти. В коде ниже показываю все три варианта. В каждом из них происходит вызов деструктора, но я сомневаюсь, в каждом ли из них производится освобождение памяти...

Интуитивно считаю, что в третьем варианте память должна освобождаться (деструктор там я вызываю вручную, иначе он не будет вызван). Оператору delete указываю "родной" указатель типа char, которому и была изначально выделена память.

Но вот первый и второй вариант... С одной стороны, я использовал new, а с другой - я ведь не выделял новую память, а указал адрес уже выделенной ранее... Вот что в данном случае происходит? Происходит ли освобождение памяти, или же всё ограничивается банальным вызовом деструктора без последующего освобождения памяти? Как можно определить, произошло ли освобождение памяти? Может какой инструмент для этого имеется в GCC и MSVisual Studio 2012?

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
#include <iostream>
#include <exception>
using namespace ::std;
 
class A{
private:
    double x;
public:
    A() : x(0) { cout << "A class; ptr: " << this << " created." << endl; } 
    ~A() { cout << "A class; ptr: " << this << " destroyed." << endl; }
};
 
int main(int argc, char* argv[])
try{    
    int x = -1; // Variants of memory clearing
    while (x < 0 || x > 2) {
        cout << "Variant (0,1,2): ";
        cin >> x;
    }
    char* p = new char[sizeof(A)]; // some memory area...
    
    A* a = new(p)A(); // Place my object in the 'p' address.
    
    // Here is my basic work to do...
    
    // Now I must to free my memory:
    if(!x){ // First variant
        delete a;           
    }
    else if (x == 1){ // Second variant
        delete reinterpret_cast<A*>(p); 
    }
    else if (x == 2){ // Third variant
        a->~A();        
        delete[] p; 
    }
    else{
        throw runtime_error("Invalid variant!");
    }
    a = nullptr;
    p = nullptr;
    
    cout << endl;   
}
catch(exception& e){
    cerr << e.what() << endl;
    return 1;
}
catch(...){
    cerr << "Unknown exception." << endl;
    return 2;
}
Спасибо.

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.10.2013, 18:39
Ответы с готовыми решениями:

Размещение объекта в памяти
Возможно ли размещение объекта в заранее выделенной памяти, например в массиве?...

Динамическое выделение памяти для объекта класса
Скажите в чем отличие между A *ptr=new A() и A *ptr=new A;

Проблаем с освобождением памяти
Работаю в Visual Studio C++ Express написал вот такой простой код: int...

мышь в определённом месте
Здравствуйте господа програмисты!!!Как поставить курсор мыши в определённое...

вывод строки в определённом месте
кто знает как выводить текст в определённом месте fseek(stdout,...) не пойдёт в...

14
Raali
639 / 343 / 74
Регистрация: 06.07.2013
Сообщений: 1,107
Завершенные тесты: 1
04.10.2013, 18:47 #2
не понял сути вопроса...
у нас есть блок памяти char A[512];
если мы хотим использовать этот же блок под класс делаем так

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Someclass
{
public:
int a;
int b;
};
 
int main(int,char**)
{
char* A = new char[512];
 
//поработали
((Someclass*)A)->a = 100;
((Someclass*)A)->b = 200;
 
//освобождаем что взяли
delete []A;
return 0;
}
0
include_brain
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
04.10.2013, 18:52  [ТС] #3
Цитата Сообщение от Raali Посмотреть сообщение
не понял сути вопроса...
у нас есть блок памяти char A[512];
если мы хотим использовать этот же блок под класс делаем так
Я в курсе и спрашивал о другом. В обозначенном мною варианте объект создаётся конструктором, поскольку зачастую экземпляры классов создаются именно так. Затем я показал три варианта освобождения ранее использовавшейся памяти. Вопрос был о том, насколько допустимы в использовании эти три варианта.
0
ct0r
Игогошка!
1784 / 686 / 43
Регистрация: 19.08.2012
Сообщений: 1,324
Завершенные тесты: 1
04.10.2013, 20:49 #4
Рабочий только третий вариант. Остальные- неопределенное поведение, так как память, выделенная оператором new, может быть освобождена только соответствующим оператором delete.

Кстати в первом варианте проверка if (!x) лишняя. delete прекрасно работает с нулевыми указателями.
0
castaway
Эксперт С++
4927 / 3034 / 453
Регистрация: 10.11.2010
Сообщений: 11,089
Записей в блоге: 10
Завершенные тесты: 1
04.10.2013, 20:53 #5
Цитата Сообщение от ct0r Посмотреть сообщение
Кстати в первом варианте проверка if (!x) лишняя. delete прекрасно работает с нулевыми указателями.
Стандартом это не гарантировано.
0
ct0r
Игогошка!
1784 / 686 / 43
Регистрация: 19.08.2012
Сообщений: 1,324
Завершенные тесты: 1
04.10.2013, 20:58 #6
Цитата Сообщение от castaway Посмотреть сообщение
Стандартом это не гарантировано.
5.3.5.2
if the value of the operand of delete is the null pointer the operation
has no effect

Ну ты почитай вначале стандарт-то.
1
castaway
04.10.2013, 21:05
  #7

Не по теме:

Действительно. Не знаю почему у меня в голове это было заложено..

0
include_brain
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
04.10.2013, 21:12  [ТС] #8
Цитата Сообщение от ct0r Посмотреть сообщение
Кстати в первом варианте проверка if (!x) лишняя. delete прекрасно работает с нулевыми указателями.
А какое отношение нулевой указатель имеет к первому варианту?
0
ct0r
Игогошка!
1784 / 686 / 43
Регистрация: 19.08.2012
Сообщений: 1,324
Завершенные тесты: 1
04.10.2013, 21:19 #9
Цитата Сообщение от include_brain Посмотреть сообщение
А какое отношение нулевой указатель имеет к первому варианту?
Точно, никакого) Но зато castaway теперь в курсе, что стандартом то гарантировано)

В общем я слишком бегло читаю код и всегда считал признаком хорошего тона числа на ноль проверять сравнением явно == 0. ! лучше проверять булевы или накрайняк указатели.
0
include_brain
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
04.10.2013, 21:22  [ТС] #10
Цитата Сообщение от ct0r Посмотреть сообщение
В общем я слишком бегло читаю код и всегда считал признаком хорошего тона числа на ноль проверять сравнением явно == 0.
Мне более импонирует форма, предложенная Стровструпом (которую я и использовал в коде). На вкус и цвет, все фломастеры разные.

Вопрос снят: почитал про "placement new".
0
badLogic
1 / 1 / 1
Регистрация: 10.04.2013
Сообщений: 41
04.10.2013, 21:27 #11
Цитата Сообщение от include_brain Посмотреть сообщение
Пусть, к примеру, у меня имеется некоторый массив объектов char (выделенный ранее динамически) и указывающий на адрес, по которому вдруг потребовалось разместить объект некоторого класса A.
А зачем так делать?
0
include_brain
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
04.10.2013, 21:32  [ТС] #12
Цитата Сообщение от badLogic Посмотреть сообщение
А зачем так делать?
линк.
0
ct0r
Игогошка!
1784 / 686 / 43
Регистрация: 19.08.2012
Сообщений: 1,324
Завершенные тесты: 1
04.10.2013, 21:35 #13
Цитата Сообщение от include_brain Посмотреть сообщение
+ это может быть разделяемая память
+ может хочется хранить определенные объекты разных типов рядом друг с другом, чтобы избежать кэш-промахов
0
badLogic
1 / 1 / 1
Регистрация: 10.04.2013
Сообщений: 41
04.10.2013, 21:44 #14
Ну там же написано, что нужно удалить всего лишь оригинальный буфер.
Может сделаете доброе дело и поделитесь, что там прочитали и какой вариант истинно правильный?
0
include_brain
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
04.10.2013, 22:09  [ТС] #15
Цитата Сообщение от badLogic Посмотреть сообщение
какой вариант истинно правильный?
третий
0
04.10.2013, 22:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.10.2013, 22:09

Не могу разобраться с классами и освобождением памяти
Есть задача. Создать класс матрица Данный класс содержит указатель на float,...

Узнать что стоит на определённом месте (0 или 1)
Уважаемые программисты! Помогите исправить код или решить задачу. Представим...

Ошибка с освобождением памяти(скорее всего) в среде Dev
Нужна помощь с исправлением кода. По окончанию выполнения программы - перестает...


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

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

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