www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to create an array of scoped objects ?

reply Flaze07 <christianseiji.cs gmail.com> writes:
e.g A is a class that emits output during destruction
{
     auto a = scoped!A();
}

how do I contain it in a container, in the Array struct ?

{
     auto a = scoped!A();
     Array!( typeof( a ) ) arr;
     foreach( i ; 0..3 ) {
         arr.insertBack( scoped!A );
     }
}

is that how you do it ?
Jul 02 2018
parent reply vit <vit vit.vit> writes:
On Tuesday, 3 July 2018 at 02:13:21 UTC, Flaze07 wrote:
 e.g A is a class that emits output during destruction
 {
     auto a = scoped!A();
 }

 how do I contain it in a container, in the Array struct ?

 {
     auto a = scoped!A();
     Array!( typeof( a ) ) arr;
     foreach( i ; 0..3 ) {
         arr.insertBack( scoped!A );
     }
 }

 is that how you do it ?
Copying/moving scoped!Class is very unsafe. scoped!Class is struct and have all of limitations of structs like no internal pointers to itself... That's why it is not copyable.
Jul 03 2018
parent reply Flaze07 <christianseiji.cs gmail.com> writes:
On Tuesday, 3 July 2018 at 07:03:43 UTC, vit wrote:
 On Tuesday, 3 July 2018 at 02:13:21 UTC, Flaze07 wrote:
 e.g A is a class that emits output during destruction
 {
     auto a = scoped!A();
 }

 how do I contain it in a container, in the Array struct ?

 {
     auto a = scoped!A();
     Array!( typeof( a ) ) arr;
     foreach( i ; 0..3 ) {
         arr.insertBack( scoped!A );
     }
 }

 is that how you do it ?
Copying/moving scoped!Class is very unsafe. scoped!Class is struct and have all of limitations of structs like no internal pointers to itself... That's why it is not copyable.
that's interesting, but I am using dsfml by jebbs( not derelict ), and I checked the code, it appears that the most of the class allocates resource and then freeing it in Destructor i.e class RenderWindow { private sfRenderWindow* _window; public { this() { _window = sfRenderWindow_create(/*parameters*/); } //couple of other functions ~this() { sfRenderWindow_destroy( window ); } } } //not a very accurate representation, but should get the message pretty clear which I am very concerned about leaking resources, the tutorial did just not use scoped!, instead it directly use new, but what about leaking resources ?
Jul 03 2018
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 3 July 2018 at 07:29:12 UTC, Flaze07 wrote:

 class RenderWindow {
     private sfRenderWindow* _window;
     public {
          this() {
             _window = sfRenderWindow_create(/*parameters*/);
          }
          //couple of other functions
          ~this() {
              sfRenderWindow_destroy( window );
          }
     }
 }
 //not a very accurate representation, but should get the 
 message pretty clear

 which I am very concerned about leaking resources, the tutorial 
 did just not use scoped!, instead it directly use new, but what 
 about leaking resources ?
The only way you're going to be leaking resources is if the app is long running and the resource objects are never collected. I'd be more concerned about the nondeterministic nature of the destructor calls, particularly what happens at app shut down if the render window destructor is called before any thing that depends on the graphics context. If the library doesn't account for that, you'll get random crashes when the app exits. If you need to release resources while the app is running, just use resource.destroy(). This will make sure the destructor is called and the object is reset to its init state, and you can maintain determinism.
Jul 03 2018
parent reply Flaze07 <christianseiji.cs gmail.com> writes:
On Tuesday, 3 July 2018 at 10:00:00 UTC, Mike Parker wrote:
 
 The only way you're going to be leaking resources is if the app 
 is long running and the resource objects are never collected. 
 I'd be more concerned about the nondeterministic nature of the 
 destructor calls, particularly what happens at app shut down if 
 the render window destructor is called before any thing that 
 depends on the graphics context. If the library doesn't account 
 for that, you'll get random crashes when the app exits.

 If you need to release resources while the app is running, just 
 use resource.destroy(). This will make sure the destructor is 
 called and the object is reset to its init state, and you can 
 maintain determinism.
hmm, I assume you know about DSFML, so... i.e void main( string args[] ) { auto win = new RenderWindow( VideoMode( 400, 400 ), "resource leak ?" ); win.close(); } //in this context, is there any memory leak ? because I saw from the source that the render window is freed during the destructor calls
Jul 03 2018
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 3 July 2018 at 10:56:26 UTC, Flaze07 wrote:

 hmm, I assume you know about DSFML, so... i.e

 void main( string args[] ) {
     auto win = new RenderWindow( VideoMode( 400, 400 ), 
 "resource leak ?" );
     win.close();
 }
 //in this context, is there any memory leak ? because I saw 
 from the source that the render window is freed during the 
 destructor calls
Even if the destructor doesn't run, there's no memory leak. Resources allocated for the process will be released on exit.
Jul 03 2018
parent reply Flaze07 <christianseiji.cs gmail.com> writes:
On Tuesday, 3 July 2018 at 14:32:01 UTC, Mike Parker wrote:
 
 Resources allocated for the process will be released on exit.
I see...but it is dependant on the OS right ? because I have seen other stuff relating to malloc as well, there are some out there that said that there is no need to free any more because the OS ( in this case windows ) will handle it
Jul 03 2018
parent reply Mike Parker <aldacron gmail.com> writes:
On Tuesday, 3 July 2018 at 14:42:58 UTC, Flaze07 wrote:
 On Tuesday, 3 July 2018 at 14:32:01 UTC, Mike Parker wrote:
 
 Resources allocated for the process will be released on exit.
I see...but it is dependant on the OS right ? because I have seen other stuff relating to malloc as well, there are some out there that said that there is no need to free any more because the OS ( in this case windows ) will handle it
As far as I know, this is true on every operating system and has always been true as long as I've been programming. The OS allocates resources for the process and doles them out when you request them, so of course it cleans it all up when you're done. Things can get buggy when you're doing multithreading, or spawning new processes (with e.g. fork()), as you can sometimes wind up with zombie threads that cause the process to not actually exit, or zombie processes that keep going in the background, taking up resources. But in general, yes, the OS will clean up behind you. You only have to worry about leaks when your application is long-lived, e.g. servers, text editors, games. If you're making a game and you aren't releasing resources when they're no longer needed, then your memory usage will keep going up the longer the game runs. DMD is a good example, too, even though it's a short-lived program. It actually never releases any memory it allocates, which is one part of its compilation speed story. That's just fine, until you start compiling template/CTFE/mixin-heavy code. Then it becomes a disadvantage as memory usage can ratchet up real quick. When I was learning C, it actually was drilled into my head that every resource allocation must have a corresponding deallocation, from the beginning to the end, and I faithfully implemented things that way for years to the extent that early versions of Derelict actually unloaded shared libraries in static destructors. However, the reason that was pushed so strongly is because it's so easy to forget to free resources during runtime in C, causing leaks and other bugs to crop up, that it's best to be religious about it so that you don't forget. But it's absolutely not necessary to go through and release every single allocated resource *at shutdown*. That said, the GC in D runs when main exits anyway, so the destructor in your example will be called. That's why I warned earlier about it being nondeterministic. For example, if you have a Texture instance that depends on the context of the RenderWindow, but the RenderWindow's destructor runs first, you could potentially see a crash on exit depending on the implementation of DSFML, SFML, and the system graphics driver.
Jul 03 2018
parent Flaze07 <christianseiji.cs gmail.com> writes:
On Tuesday, 3 July 2018 at 15:06:28 UTC, Mike Parker wrote:
 ..
 That said, the GC in D runs when main exits anyway, so the 
 destructor in your example will be called. That's why I warned 
 earlier about it being nondeterministic. For example, if you 
 have a Texture instance that depends on the context of the 
 RenderWindow, but the RenderWindow's destructor runs first, you 
 could potentially see a crash on exit depending on the 
 implementation of DSFML, SFML, and the system graphics driver.
I see, so that's what you meant, thank you
Jul 03 2018