F
Francesco S. Carta
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 << endl;
}
// zero-initialized creation
new(arr_ptr) int[n]();
// prints zeros
for (int i = 0; i < n; ++i) {
cout << arr_ptr << 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.data << endl;
}
// zero-initialized creation
new(arr_ptr) POD[n]();
// prints zeros
for (int i = 0; i < n; ++i) {
cout << arr_ptr.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:erived(int)" << endl;
}
Derived(const Derived& d) : ptr(new int(*d.ptr)) {
cout << "Derived:erived(const Derived&)" << endl;
}
Derived& operator=(const Derived& d) {
cout << "Derived:perator=(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:erived(123)
new(ptr) Derived;
// prints 123
cout << ptr->data() << endl;
// call destructor
ptr->~Derived();
// calls Derived:erived(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:erived(123) n-times
new(arr_ptr) Derived[n];
// prints 123 n-times
for (int i = 0; i < n; ++i) {
cout << arr_ptr.data() << endl;
}
// call destructors
for (int i = n; i > 0; --i) {
arr_ptr[i-1].~Derived();
}
// calls Derived:erived(123) n-times
new(arr_ptr) Derived[n]();
// prints 123 n-times
for (int i = 0; i < n; ++i) {
cout << arr_ptr.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.
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 << endl;
}
// zero-initialized creation
new(arr_ptr) int[n]();
// prints zeros
for (int i = 0; i < n; ++i) {
cout << arr_ptr << 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.data << endl;
}
// zero-initialized creation
new(arr_ptr) POD[n]();
// prints zeros
for (int i = 0; i < n; ++i) {
cout << arr_ptr.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:erived(int)" << endl;
}
Derived(const Derived& d) : ptr(new int(*d.ptr)) {
cout << "Derived:erived(const Derived&)" << endl;
}
Derived& operator=(const Derived& d) {
cout << "Derived:perator=(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:erived(123)
new(ptr) Derived;
// prints 123
cout << ptr->data() << endl;
// call destructor
ptr->~Derived();
// calls Derived:erived(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:erived(123) n-times
new(arr_ptr) Derived[n];
// prints 123 n-times
for (int i = 0; i < n; ++i) {
cout << arr_ptr.data() << endl;
}
// call destructors
for (int i = n; i > 0; --i) {
arr_ptr[i-1].~Derived();
}
// calls Derived:erived(123) n-times
new(arr_ptr) Derived[n]();
// prints 123 n-times
for (int i = 0; i < n; ++i) {
cout << arr_ptr.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.