Thread overview
Pointer problems, changing for no reasons
Jun 09, 2016
Begah
Jun 09, 2016
cy
Jun 10, 2016
Begah
Jun 10, 2016
Begah
Jun 10, 2016
Ali Çehreli
Jun 10, 2016
ketmar
Jun 10, 2016
ketmar
June 09, 2016
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?
June 09, 2016
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..
June 10, 2016
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 ).
June 10, 2016
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];
}
June 10, 2016
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

June 10, 2016
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;
June 10, 2016
ooops. that solution is provided in Ali's book. sorry for the noise.