Are there any methods like isDestroyed or isDisposed to detect whether some object is destroyed or not?
Hello! We have object, for example, objA. ObjectAType objA = new ObjectAType(...); // we have a many references to objA void someFunction1(...) { // destroying the objA destroy(one_of_the_refToObjA); // } void someFunction2() { // "segmentation fault" if the objA is destroyed another_refToObjA.method1(); // I need a safe way (without using signals) to detect whether object // destroyed or not, like this // if (!isDestroyed(another_refToObjA)) // another_refToObjA.method1(); } // call functions someFunction1(..); // . some other operations... // the objectA (objA) is destroyed, but debugger shows us a not null reference // to that objA. However, when we try to call some methods of objectA or // try to use it's variables we get a "segmentation fault" error (in // someFunction2, when objA is destroyed). someFunction2(...); Thanks.
Re: Are there any methods like isDestroyed or isDisposed to detect whether some object is destroyed or not?
import std.stdio; class ObjectAType { bool ok; this() {ok = true;} } void main() { auto a = new ObjectAType; assert(a.ok); destroy(a); assert(!a.ok); // a has been destroyed. } This method of detection of collected objects is what I needed. Thanks to everybody for your advise.
Re: Are there any methods like isDestroyed or isDisposed to detect whether some object is destroyed or not?
Thank you very much, Steven!
strange work of GC
class C1 { int a1, b1, c1, d1, e1; string sdb1; this(string s) { sdb1 = s; a1=90; b1=19; d1=22; e1=23; } ~this() { if (sdb1 == "lll") { sdb1 = "aaa"; } writeln("disposing "~sdb1); } } class C2 { C1 c1 = null; int a2, b2, c2, d2, e2; string sdb2; this(string s) { sdb2 = s; a2=90; b2=19; d2=22; e2=23; } ~this() { c1=null; writeln("disposing "~sdb2); } }; void fn1() { writeln("start of fn1"); C2[] arr = new C2[1_000_000]; for (int i=0; iThis code never starts the garbage collector, but after execution fn1 nothing refers to arr. As I think, the garbage collector should start destoying of the C1 and C2 objects of arr array during the "while" cycle prosess, but this does not happen. Dtors are not called. If I use the manual destroying of objects C1 and C2 by "destroy" method, the dtors of C1 and C2 objects are normally called, but it can't be safe. If I use the GC.collect method after fn1, I get an error: "core.exception.InvalidMemoryOperationError@(0)". Is this a bug of GC or I do something wrong? Thanks.
Re: strange work of GC
If a "destroy" method is used together with GC inside of my app,it makes my app unstable. In this case I need to choose how to destroy my objects: 1) always manually by method "destroy", but without GC; 2) or always automatically by GC, but without using the "destroy" method. In the first case I need to know how can I disable the automatic GC in my app? In the second case - how can I disable the "destroy" method calls inside of my app?
Re: strange work of GC
Why do you want to use destroy? The destroy method always calls a dtor of the objects, where I can destroy some object's variables in that order that I need, I think. And this is very good for me, because I have a full control of the object's destroying stage. But if I use the GC, I have no garanties that the dtors will be called, therefore some of my methods will not be called too. In this case it would be better to disable automatically garbage collection in my D app, elsewise once app will be failed (manual destroying idiom). On another hand if I use only GC (automatically destroying idiom), I have to disable "destroy" method and all dtors of the objects, so that nobody can call "destroy" method. Otherwise app will be failed once again. Two idioms are existing in one app at the same time have more possiblities for D programmers to make hard errors in their code, and it is confusing me sometimes. For example, .Net (C#) have no dtors and "destroy" methods. It is a very good idiom, because no confusions occur.
GC has a "barbaric" destroyng model, I think
If we are using a DMD realization of destroying of objects, happens the following: at the calling the «destroy» method the calling of dtor takes place always, and then the object which is being destroyed is initialized by the default state. In other words, after calling «destroy» method, there is no way of getting an access to the members of the object that is being destroyed (it is meant, that the members are the references). GC works the same way. This approach in case of manual calling of «destroy» method has predictable and understandable consequences (there is no reasone to use the object being destroyed). But if GC performes the destroying of the objects, a lot of errors appear at the accessing to the members which are references, because some of them have already been destroyed (access to the members is realized in dtors). Such situations can be avoided, by using «@nogc» keyword. Howewer «@nogc» keyword doesn't protect us from using the references in dtors: we can assign some values to the refernces, we can have access to some members by the references and assign them some values.That is not correct in itself. If GC starts destroying some group of the objects, it could be more correct, if the calls of dtros are occured of all objects in a group before phisical memory releasing. Or GC must call dtors of the objetcts only, which noone refers to.
Re: GC has a "barbaric" destroyng model, I think
OK. there is some example: // we're using an OpenGL class A { protected int m_tex; this() { // texture has been created in video memory. there is no GC resource. glGenTexture(1, &m_tex); glTexImage2D(); // texture in video memory } ~this() { // release texture in video memory glDeleteTextures(1, &m_tex); } } void foo() { // we do some operations... A[] arrA = new A[1_000_000]; for (int i; i // do some operations... and return without explicit disposing of arrA } main(...) { while(app.isNotExit) { foo(); } } if GC does not guarantee the calling of dtor we can't be sure that some textures will be destroyed. It will be followed by overflowing of the video memory. And it is obvious, becouse we have no way to detect when the objects are destroyed. The video memory will leaks.
Re: GC has a "barbaric" destroyng model, I think
On Thursday, 12 February 2015 at 12:29:47 UTC, Marc Schütz wrote: Exactly. That's why it's wrong to rely on the GC if you need deterministic resource management. It's simply the wrong tool for that. Unfortunately, the "right" tools are a bit awkward to use, for the time being. I still have hopes that we can finally get our act together and get a usable `scope` implementation, which can then be used to provide better library defined container types as well as efficient reference counting. If we can't relay on GC wholly, there is no need for GC. All of the objects, that I can create, I can destroy manually by myself, without any doubtful GC destroying attempts.
Re: GC has a "barbaric" destroyng model, I think
On Thursday, 12 February 2015 at 13:11:48 UTC, ketmar wrote: sure. but when it comes, for example, for big data structures with complex cross-references, you'll inevitably found that you either leaking memory, or writing your own half-backed semi-working GC realization. ah, good luck doing effecient refcounting on slices, for example. and they aren't even remotely complex. Well. What is the trouble if dtors are always (it is garanteed) called by GC before their phisical destroying? It will help to avoid many awkward situations.
shared interfaces
interface IA { void fnA(); } interface IB { void fnB(); } shared interface IC : IA, IB { void fnC(); } shared class C : IA, IB { override void fnA() // Error: function main.C.fnA does not override any function, did you mean to override 'main.IA.fnA'? { } override void fnB() // Error: function main.C.fnB does not override any function, did you mean to override 'main.IA.fnA'? { } shared class D : IC { override void fnC() { } override void fnA() // Error: function main.D.fnA does not override any function, did you mean to override 'main.IA.fnA'? { } override void fnB() // Error: function main.D.fnB does not override any function, did you mean to override 'main.IB.fnB'? { } } what is wrong in declarations, if I need to declare shared classes D and C?
Re: shared interfaces
On Sunday, 15 February 2015 at 11:30:46 UTC, anonymous wrote: On Sunday, 15 February 2015 at 10:43:46 UTC, Andrey Derzhavin wrote: what is wrong in declarations, if I need to declare shared classes D and C? `shared` on a class/interface makes all members shared. And that's all it does. So this: interface IA { void fnA(); } shared class C : IA { override void fnA() {} } is the same as this: interface IA { void fnA(); } class C : IA { override void fnA() shared {} } But you can't override a non-shared method with a shared one, hence the error. So, if you need to override non-shared methods, you can't mark the whole class shared. Instead, you have to mark the shared members individually. Like so: interface IA { void fnA(); } shared interface IC : IA { void fnC(); } class D : IC { override void fnC() shared {} override void fnA() {} } Try to compile your example, it is wrong.
Re: shared interfaces
On Sunday, 15 February 2015 at 14:59:20 UTC, anonymous wrote: Hm? Works for me. What error do you get, or what doesn't work? Which compiler are you using, which version? The error "Error: function main.C.fnA does not override any function, did you mean to override 'main.IA.fnA'?" has occured (( I'm using DMD 2.066.1 compiler.
Re: shared interfaces
On Sunday, 15 February 2015 at 14:59:20 UTC, anonymous wrote: Sorry everything is OK. It's my fault. Thanks))