What's the use case of clear?
Steven Schveighoffer
schveiguy at yahoo.com
Tue Aug 10 10:58:36 PDT 2010
On Tue, 10 Aug 2010 13:01:37 -0400, Lutger <lutger.blijdestijn at gmail.com>
wrote:
> Honestly I think that clear() as it does too much, but this is what I
> think was
> intended:
>
> Class Connection {
> invariant() { assert( pool !is null); }
>
> ConnectionPool pool = null;
> bool isOpen = false;
>
> this() {
> pool = ConnectionPool.get();
> enforce(pool !is null);
> }
> this(string connectionString) {
> this();
> connect(pool, connectionString);
> isOpen = true;
> }
>
> ~this() {
> disconnect(pool, connectionString);
> }
> }
No, this is bad. ~this cannot access any GC resources. Although you
forgot to store it, connectionString may be a GC-allocated resource, so it
may be invalid by the time the destructor is called. The only way to fix
this is to malloc the string:
Class Connection {
private string connectionString;
...
this(string connectionString) {
this();
connect(pool, connectionString); // note, we use the GC'd version
in case connect stores it.
this.connectionString =
(cast(immutable(char)*)malloc(connectionString.length))[0..connectionString.length];
}
...
~this() {
// since I malloc'd connectionString, I know the GC didn't collect
it.
disconnect(pool, connectionString);
free(connectionString.ptr); // clean up my non-GC resources
}
}
In fact, it might even be illegal to use pool. If at the end of the
program, the pool is destroyed, and then your object gets destroyed, you
are screwed.
It is one of the severe limitations of the GC. I wish there was a way to
mark a piece of memory as "owned", that would be nice to have. But even
then, you need to own all the data you deal with in the destructor. You
can't rely on simple pointers to objects you don't own, they may be
invalid.
-Steve
More information about the Digitalmars-d
mailing list