www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Pointer problems, changing for no reasons

reply Begah <mathieu.roux222 gmail.com> writes:
I have a really weird bug in my application, i succeeded in 
making a small program with the bare munimum to show that bug.

The full source code of the application + a dub.json file are at 
https://github.com/Begah/D_Pointer_Problem ( < 300 LOC )

I have a template called ResourceManager (asset.d) which takes in 
an asset ( Texture or Model ) and return a handle to it.
A handle has a pointer to the asset as well as a pointer to an 
integer ( referenceCounter ) both allocated by C's malloc.

First, i call ResourceManager!(Model).get("Coin.obj"). This 
function checks if that resource is already loaded, if not ( and 
in this case it's not ) then it calls model.loadModel();
A model has an array of textures, for simplicity sakes, in this 
example i only add one texture.
Before model.loadModel returns the struct created, i first prints 
the location and value of the referenceCounter of the first 
texture in the model :
	Logger.info(model.textures[0].referenceCount);
	Logger.info(*model.textures[0].referenceCount);
	
For example it prints :
	INFO (source\model.d|38) : 597F08     <- Location of the 
referenceCounter
	INFO (source\model.d|39) : 2          <- Value of the 
referenceCounter
	
Next, model.loadModel return the model structure to 
ResourceManager!(Model).get("Coin.obj") :
	AssetType asset = loadFunc(asset_name, args);

	static if(is(model.Model == AssetType)) {
		Logger.info(asset.textures[0].referenceCount);
		Logger.info(*asset.textures[0].referenceCount);
		Logger.info(asset.textures[0].referenceCount);
	}
	
And this is where my application, when 
ResourceManager!(Model).get("Coin.obj") prints the location and 
value of the first texture's referenceCounter.
This prints :
	INFO (source\assets.d|83) : 597F08    <- Location of the 
referenceCounter
	INFO (source\assets.d|84) : 1         <- Value of the 
referenceCounter
	INFO (source\assets.d|85) : 434A7C    <- Location of the 
referenceCounter ( again )
	
These three lines of code does nothing except prints to the 
console.
As you can see, for some reason, the location of the 
referenceCounter changes for no apparant reason.
I have done many different test and changes but i can't 
understand why this bug is happening, any ideas?
Jun 09 2016
parent reply cy <dlang verge.info.tm> writes:
I can't help but notice that loadModel is not a static member 
function, yet you don't seem to call it with a Model object in 
your "get" function.

Also have a look at std.typecons.RefCounted if you want reference 
counted data..
Jun 09 2016
parent reply Begah <mathieu.roux222 gmail.com> writes:
On Thursday, 9 June 2016 at 19:00:42 UTC, cy wrote:
 I can't help but notice that loadModel is not a static member 
 function, yet you don't seem to call it with a Model object in 
 your "get" function.

 Also have a look at std.typecons.RefCounted if you want 
 reference counted data..
loadModel is not a method, it is a function. Being a function it doesn't have a 'this' so doesn't need to be called with an object. Also, i tried using std.typecons.RefCounted but i didn't like the lack of control i had over it ( refCount is private and only has a getter method ).
Jun 10 2016
parent reply Begah <mathieu.roux222 gmail.com> writes:
On Friday, 10 June 2016 at 07:28:44 UTC, Begah wrote:
 On Thursday, 9 June 2016 at 19:00:42 UTC, cy wrote:
 I can't help but notice that loadModel is not a static member 
 function, yet you don't seem to call it with a Model object in 
 your "get" function.

 Also have a look at std.typecons.RefCounted if you want 
 reference counted data..
loadModel is not a method, it is a function. Being a function it doesn't have a 'this' so doesn't need to be called with an object. Also, i tried using std.typecons.RefCounted but i didn't like the lack of control i had over it ( refCount is private and only has a getter method ).
I have found the problem and i still don't understand why i was a problem : struct Model { TextureType[] textures; this(TextureType[] textures...) { this.textures = textures[]; } } In the constructor, i copied the textures to the model's inner texture array, and for some reason this caused the problem. So i needed to change to something like : this.textures.length = textures.length; foreach(i; 0..textures.length) { this.textures[i] = textures[i]; }
Jun 10 2016
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/10/2016 01:32 AM, Begah wrote:

 I have found the problem and i still don't understand why i was a 
problem :
 struct Model
 {
     TextureType[] textures;

     this(TextureType[] textures...) {
         this.textures = textures[];
     }
 }
Yeah, that's a bug because the argument array is on the stack and has a short lifetime. (I wish the compiler would warn about that.) As a result, this.textures is now a reference to elements that are destroyed upon constructor exit. I have some more explanation of it under the "Variadic function arguments have a short lifetime" section here: http://ddili.org/ders/d.en/parameter_flexibility.html Ali
Jun 10 2016
prev sibling parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Friday, 10 June 2016 at 08:32:40 UTC, Begah wrote:
 In the constructor, i copied the textures to the model's inner 
 texture array, and for some reason this caused the problem.
 So i needed to change to something like :

 this.textures.length = textures.length;
 foreach(i; 0..textures.length) {
 	this.textures[i] = textures[i];
 }
the easier one-line solution: this.textures = textures.dup;
Jun 10 2016
parent ketmar <ketmar ketmar.no-ip.org> writes:
ooops. that solution is provided in Ali's book. sorry for the 
noise.
Jun 10 2016