Dynamic memory management, straightening my understanding of its
details
Hi there,
I'm trying to understand the details of the dynamic memory management.
These are the various sections I've read these days:
1.7 [intro.memory]
3.7.3 [basic.stc.dynamic]
5.3.4 [expr.new]
5.3.5 [expr.delete]
12.5 [class.free]
18.4.1 [lib.new.delete]
20.4 [lib.memory]
The last sections above are quite technical and wide, I'm still far from
having any decent grasp on them.
Before going on I need to clear out if what I understood so far is correct.
I wrote the following at the best of my comprehension and, as far as I
can tell, it should be a well-defined C++ program, please tell me if and
where I've gone off the track:
//-------
#include <iostream>
#include <new>
using namespace std;
const int n = 2;
void int_test() {
cout << " # int_test()" << endl;
// allocate
int* ptr = static_cast<int*>(
operator new(sizeof(int))
);
// non-initialized creation
new(ptr) int;
// prints garbage
cout << *ptr << endl;
// zero-initialized creation
new(ptr) int();
// prints zero
cout << *ptr << endl;
// deallocate
operator delete(ptr);
cout << endl << " # int_test(), array version" << endl;
// allocate
int* arr_ptr = static_cast<int*>(
operator new[](n * sizeof(int))
);
// non-initialized creation
new(arr_ptr) int[n];
// prints garbage values
for (int i = 0; i < n; ++i) {
cout << arr_ptr[i] << endl;
}
// zero-initialized creation
new(arr_ptr) int[n]();
// prints zeros
for (int i = 0; i < n; ++i) {
cout << arr_ptr[i] << endl;
}
// deallocate
operator delete[](arr_ptr);
}
struct POD {
int data;
};
void POD_test() {
cout << " # POD_test()" << endl;
// allocate
POD* ptr = static_cast<POD*>(
operator new(sizeof(POD))
);
// non-initialized creation
new(ptr) POD;
// prints garbage
cout << ptr->data << endl;
// zero-initialized creation
new(ptr) POD();
// prints zero
cout << ptr->data << endl;
// deallocate
operator delete(ptr);
cout << endl << " # POD_test(), array version" << endl;
// allocate
POD* arr_ptr = static_cast<POD*>(
operator new[](n * sizeof(POD))
);
// non-initialized creation
new(arr_ptr) POD[n];
// prints garbage values
for (int i = 0; i < n; ++i) {
cout << arr_ptr[i].data << endl;
}
// zero-initialized creation
new(arr_ptr) POD[n]();
// prints zeros
for (int i = 0; i < n; ++i) {
cout << arr_ptr[i].data << endl;
}
// deallocate
operator delete[](arr_ptr);
}
struct Base {
virtual int data() const = 0;
virtual ~Base() {}
};
class Derived : public Base {
public:
Derived(int i = 123) : ptr(new int(i)) {
cout << "Derived::Derived(int)" << endl;
}
Derived(const Derived& d) : ptr(new int(*d.ptr)) {
cout << "Derived::Derived(const Derived&)" << endl;
}
Derived& operator=(const Derived& d) {
cout << "Derived::operator=(const Derived&)" << endl;
*ptr = *d.ptr;
return *this;
}
~Derived() {
cout << "Derived::~Derived()" << endl;
delete ptr;
}
int data() const {
return *ptr;
}
private:
int* ptr;
};
void Derived_test() {
cout << " # Derived_test()" << endl;
// allocate
Derived* ptr = static_cast<Derived*>(
operator new(sizeof(Derived))
);
// according to 12.1p8 [class.ctor]
// this calls Derived::Derived(123)
new(ptr) Derived;
// prints 123
cout << ptr->data() << endl;
// call destructor
ptr->~Derived();
// calls Derived::Derived(321)
new(ptr) Derived(321);
// prints 321
cout << ptr->data() << endl;
// call destructor
ptr->~Derived();
// deallocate
operator delete(ptr);
cout << endl << " # Derived_test(), array version" << endl;
// allocate
Derived* arr_ptr = static_cast<Derived*>(
operator new[](n * sizeof(Derived))
);
// calls Derived::Derived(123) n-times
new(arr_ptr) Derived[n];
// prints 123 n-times
for (int i = 0; i < n; ++i) {
cout << arr_ptr[i].data() << endl;
}
// call destructors
for (int i = n; i > 0; --i) {
arr_ptr[i-1].~Derived();
}
// calls Derived::Derived(123) n-times
new(arr_ptr) Derived[n]();
// prints 123 n-times
for (int i = 0; i < n; ++i) {
cout << arr_ptr[i].data() << endl;
}
// call destructors
for (int i = n; i > 0; --i) {
arr_ptr[i-1].~Derived();
}
// deallocate
operator delete[](arr_ptr);
}
int main() {
int_test();
cout << "===========" << endl;
POD_test();
cout << "===========" << endl;
Derived_test();
return 0;
}
//-------
Thank you for your attention.
--
FSC - http://userscripts.org/scripts/show/59948
http://fscode.altervista.org - http://sardinias.com