Jump to page: 1 24  
Page
Thread overview
How to use destroy and free.
Apr 24, 2022
Alain De Vod
Apr 25, 2022
Salih Dincer
Apr 25, 2022
Ali Çehreli
Apr 25, 2022
Alain De Vos
Apr 25, 2022
Salih Dincer
Apr 25, 2022
Alain De Vos
Apr 25, 2022
Stanislav Blinov
Apr 25, 2022
Alain De Vos
Apr 25, 2022
Alain De Vos
Apr 25, 2022
H. S. Teoh
Apr 26, 2022
Alain De Vos
Apr 25, 2022
frame
Apr 26, 2022
Ali Çehreli
Apr 25, 2022
Ali Çehreli
Apr 30, 2022
Dukc
Apr 30, 2022
Tejas
Apr 30, 2022
Dukc
May 03, 2022
Alain De Vos
May 03, 2022
Mike Parker
May 03, 2022
Alain De Vos
May 03, 2022
Ali Çehreli
May 03, 2022
H. S. Teoh
May 04, 2022
Mike Parker
May 04, 2022
forkit
May 04, 2022
Mike Parker
May 04, 2022
forkit
May 04, 2022
Mike Parker
May 04, 2022
forkit
May 04, 2022
cc
May 04, 2022
forkit
May 04, 2022
cc
May 04, 2022
Ali Çehreli
May 04, 2022
forkit
May 04, 2022
H. S. Teoh
May 04, 2022
forkit
May 04, 2022
H. S. Teoh
May 03, 2022
Tejas
April 24, 2022

Is this a correct program to explicit call destroy & free ?

void main(){
    int[] i=new int[10000];
    import object: destroy;
    destroy(i);
    import core.memory: GC;
    GC.free(GC.addrOf(cast(void *)(i.ptr)));
}
April 25, 2022

On Sunday, 24 April 2022 at 21:00:50 UTC, Alain De Vod wrote:

>

Is this a correct program to explicit call destroy & free ?

void main(){
    int[] i=new int[10000];
    import object: destroy;
    destroy(i);
    import core.memory: GC;
    GC.free(GC.addrOf(cast(void *)(i.ptr)));
}

Yes, first destroy() then free()...

import std.stdio;
import object: doDestroy = destroy;
import core.memory : MEM = GC;

void disposeOf(T)(T obj)
{
    auto mem = cast(void*) obj;
    scope (exit) MEM.free(mem);
    doDestroy(obj);
}

void main()
{
  int[] i = new int[1024];
  i[$-1] = 41;

  doDestroy(i);
  MEM.free(i.ptr);
  // You don't need to addrOf(cast(void*)i)

  //i.length = 1024;
  //assert(i[$-1] == 0);
  //i[$-1].writeln(" am there?");

  if (i !is null)
  {
    "still alive!".writeln;
    disposeOf(i);
  }
  "bye...".writeln;
}

SDB@79

April 24, 2022
On 4/24/22 14:00, Alain De Vod wrote:
> Is this a correct program to explicit call destroy & free ?

destroy() is called with the object that you want its destructor to be executed on. This is very rare in D because when the destructor has to be called, one relies on the lifetime of a struct object, or uses scope(exit), scope(success), or scope(failure).

free is called on memory that you explicitly allocated.

> ```
> void main(){
>      int[] i=new int[10000];
>      import object: destroy;
>      destroy(i);

That does not have any effect for an int array because int does not have any destructor.

Assuming you are asking for struct elements, let me try:

import std.stdio;

struct S {
  ~this() {
    writeln(__FUNCTION__);
  }
}

void main() {
  auto arr = [ S() ];
  writeln("calling destroy");
  destroy(arr);
  writeln("called destroy");
  writeln("leaving main");
}

No, destroy'in an array does not call the destructor of the elements:

calling destroy  <-- No destructor called here
called destroy
leaving main
deneme.S.~this

And that is expected because arrays don't have destructors. If you want to destroy the elements of an array, you must call destroy for each element. One way:

  import std.algorithm : each;
  arr.each!((ref e) => destroy(e));

Now the output has our destructor call:

calling destroy
deneme.S.~this
called destroy  <-- HERE
leaving main
deneme.S.~this

The final destructor is called for the .init state of the element because destroy() blits the .init state on objects.

>      import core.memory: GC;
>      GC.free(GC.addrOf(cast(void *)(i.ptr)));

That is wrong because you did not allocate that address yourself.

It is further wrong for arrays in general because there may be slices to arrays, which you would not free the elements of.

Ali

April 24, 2022
On 4/24/22 17:26, Salih Dincer wrote:

> first destroy() then free()...

Makes sense only if we allocated the memory.

> import object: doDestroy = destroy;

I like adding 'do' to verbs that can be confused with nouns. For example, because 'copy' is both a noun and a verb, I think it helps when we name a function as 'doCopy'. However, because 'destroy' is already a verb, I would leave it alone. :)

>    MEM.free(i.ptr);
>    // You don't need to addrOf(cast(void*)i)

Good point about i.ptr but that free() does not or should not do anything because it is "memory not originally allocated by this garbage collector":

  https://dlang.org/phobos/core_memory.html#.GC.free

Well... maybe it was allocated by that garbage collector and may be it points to the beginning of an allocated block but we don't know that. I wouldn't call free() on an array's memory.

Ali

April 25, 2022
Ali, thanks for the answer but i rephrase my question.
How to destroy,free , for garbage-collection-cycle in the destructor of this code :

```
import std.stdio: writeln;

class C{
	int[] i=null;
	this(){
		writeln("Allocate heap");
		i=new int[10000];
		writeln(typeid(typeof(i)));
		writeln(typeid(typeof(i.ptr)));
		i[9000]=5;
	}
	~this(){
		writeln("Free heap");
		import object: destroy;
		import core.memory: GC;
		i=null;
                // But How to force destroy and free , GC-cycle for heap object i ?
	};
}

struct S{
	C c;
	@disable this();
	this(int dummy){c=new C;}
}

void main(){
	enum _=0;
	writeln(S(_).c.i[9000]);
}
```
April 25, 2022

On Monday, 25 April 2022 at 10:13:43 UTC, Alain De Vos wrote:

>

destructor of this code :

 ~this(){
	writeln("Free heap");
	import object: destroy;
	import core.memory: GC;
	i=null;
	// But How to force destroy and free , GC-cycle for heap object i ?
};

If you use destroy in destructor (~this), it will call destructor two times but thats not error.

SDB@79

April 25, 2022

Note, heap object i is not an instance of the class C

April 25, 2022
On Monday, 25 April 2022 at 10:13:43 UTC, Alain De Vos wrote:
> Ali, thanks for the answer but i rephrase my question.
> How to destroy,free , for garbage-collection-cycle in the destructor of this code :
>
> // But How to force destroy and free , GC-cycle for heap object i ?

Short answer: use `destroy`. Long answer: don't do that.

https://dlang.org/spec/class.html#destructors

GC is not guaranteed to call destructors, and in fact it may run into situations when it can't (i.e. objects pointing to one another). Neither does it specify in what order destructors of GC-allocated objects are run (when they are run). If you need deterministic destruction e.g. for resource management, do not use GC.
April 25, 2022
> GC-allocated objects are run (when they are run). If you need deterministic destruction e.g. for resource management, do not use GC.

Descend destroy and free functions should return something.
"destroy" should return if the destructor was called successfully.
"free" should return the exact number of bytes freed on the heap.

Probably this is not implemented in the library because it is probably "buggy".

April 25, 2022
Could thc or hboehm provide solutions ?
« First   ‹ Prev
1 2 3 4