managing free store objects

stroustrup said:
[2] When you construct an object on the free store, place its pointer into a manager object(sometimes called a handle) with a destructor that will destroy it.


is this what he meant?
1
2
3
4
5
6
7
8
9
10
11
12
13
class Manager {
	std::vector<int*> vp;
public:
	Manager() {}
	~Manager() {
		for (auto& p : vp)
			delete[] p;
	}

	void push_back(int* p) {
		vp.push_back(p);
	}
};


Because I tested it and it seems not working for me:
1
2
3
4
5
6
void f()
{
	Manager manager;
	int* p = new int;
	manager.push_back(p);
} // manager implicitly destroyed -> destructor called -> p should be deleted. 
Last edited on
> is this what he meant?

No.

He goes on to give examples of typical manager objects:
Examples are string, vector and all the other standard-library containers, unique_ptr (§5.2.1, §34.3.1), and shared_ptr (§5.2.1, §34.3.2). Wherever possible, have that manager object be a scoped variable. Many classical uses of free store can be eliminated by using move semantics (§3.3, §17.5.2) to return large objects represented as manager objects from functions.

This rule [2] is often referred to as RAII (‘‘Resource Acquisition Is Initialization’’; §5.2, §13.3) and is the basic technique for avoiding resource leaks and making error handling using exceptions simple and safe. The standard-library vector is an example of these techniques:
...

What about this for example:
1
2
3
4
5
6
7
8
9
10
class My_type {
    int* data;
public:
    My_type(int s)
        :data(new int[s]) {
        for (int i = 0; i < s; ++i)
            data[i] = 0;
    }
    ~My_type() { delete[] data; }
};
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <vector>

class My_type {

    std::vector<int> data;

    public:
        
        My_type( std::size_t s ) : data(s) {}

        // destructor etc. are implicitly declared
        // rule of zero: https://en.cppreference.com/w/cpp/language/rule_of_three 
};
Sorry, I asked too many questions, last one I promise:
You have used std::vector because it takes care of its elements right? so that we don't have to worry about them, that's the meaning of a handle right?
Last edited on
Yes.

77. Use vector and string instead of arrays.

Summary

Why juggle Ming vases? Avoid implementing array abstractions with C-style arrays, pointer arithmetic, and memory management primitives. Using vector or string not only makes your life easier, but also helps you write safer and more scalable software.

Discussion

Buffer overruns and security flaws are, hands down, a front-running scourge of today's software. Silly limitations due to fixed-length arrays are a major annoyance even when within the limits of correctness. Most of these are caused by using bare C-level facilities — such as built-in arrays, pointers and pointer arithmetic, and manual memory management — as a substitute for higher-level concepts such as buffers, vectors, or strings.

Here are some reasons to prefer the standard facilities over C-style arrays:

• They manage their own memory automatically: No more need for fixed buffers of "longer than any reasonable length" ("time bombs" is a more accurate description), or for frantic realloc'ing and pointer adjustment.

• They have a rich interface: You can implement complex functionality easily and expressively.

• They are compatible with C's memory model: vector and string::c_str can be passed to C APIs—in both read and write modes, of course. In particular, vector is C++'s gateway to C and other languages. (See Items 76 and 78.)

• They offer extended checking: The standard facilities can implement (in debug mode) iterators and indexing operators that expose a large category of memory errors. Many of today's standard library implementations offer such debugging facilities—use them! (Run, don't walk, to Item 83.)

• They don't waste much efficiency for all that: Truth be told, in release mode vector and string favor efficiency over safety when the two are in tension. Still, all in all, the standard facilities offer a much better platform for creating safe components than do bare arrays and pointers.

• They foster optimizations: Modern standard library implementations include optimizations that many of us mere mortals have never thought of.

An array can be acceptable when its size really is fixed at compile time (e.g., float[3] for a three-dimensional point; switching to four dimensions would be a redesign anyway).

Sutter and Alexandrescu in 'C++ Coding Standards: 101 Rules, Guidelines, and Best Practices'
Topic archived. No new replies allowed.