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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
include_brain
3 / 3 / 0
Регистрация: 13.09.2013
Сообщений: 38
#1

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

04.10.2013, 18:39. Просмотров 557. Ответов 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
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Динамическое размещение объекта в определённом месте памяти с последующим её освобождением (C++):

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

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

Проблаем с освобождением памяти - C++
Работаю в Visual Studio C++ Express написал вот такой простой код: int main(){ char *n; n=new char; n=&quot;Text&quot;; delete n; ...

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

вывод строки в определённом месте - C++
кто знает как выводить текст в определённом месте fseek(stdout,...) не пойдёт в данном случае нельзя приминить Добавлено через 12...

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

14
Raali
623 / 327 / 34
Регистрация: 06.07.2013
Сообщений: 1,065
Завершенные тесты: 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
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,292
Завершенные тесты: 1
04.10.2013, 20:49 #4
Рабочий только третий вариант. Остальные- неопределенное поведение, так как память, выделенная оператором new, может быть освобождена только соответствующим оператором delete.

Кстати в первом варианте проверка if (!x) лишняя. delete прекрасно работает с нулевыми указателями.
0
castaway
Эксперт С++
4885 / 3020 / 370
Регистрация: 10.11.2010
Сообщений: 11,078
Записей в блоге: 10
Завершенные тесты: 1
04.10.2013, 20:53 #5
Цитата Сообщение от ct0r Посмотреть сообщение
Кстати в первом варианте проверка if (!x) лишняя. delete прекрасно работает с нулевыми указателями.
Стандартом это не гарантировано.
0
ct0r
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,292
Завершенные тесты: 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
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,292
Завершенные тесты: 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 / 0
Регистрация: 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
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,292
Завершенные тесты: 1
04.10.2013, 21:35 #13
Цитата Сообщение от include_brain Посмотреть сообщение
+ это может быть разделяемая память
+ может хочется хранить определенные объекты разных типов рядом друг с другом, чтобы избежать кэш-промахов
0
badLogic
1 / 1 / 0
Регистрация: 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
Привет! Вот еще темы с ответами:

Узнать что стоит на определённом месте (0 или 1) - C++
Уважаемые программисты! Помогите исправить код или решить задачу. Представим себе бесконечную последовательность цифр, составленную из...

Проблемы с delete [], программа периодически аварийно завершается на строке с освобождением памяти. - C++
Добрый день! Столкнулся со следующей задачей: в программе требуется довольно часто изменять размеры массива, для чего использую...

Динамическое размещение массива структур - C++
В коде ниже создается массив из трех структур cs и инициализируется некими значениями. #include &quot;stdafx.h&quot; #include &lt;iostream&gt; struct...

Динамическое размещение массива структур - C++
Подскажите пожалуйста, как динамически разместить массив из нескольких структур, используя операцию new??


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

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

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