www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Different behaviour of new and malloc

reply "Namespace" <rswhite4 googlemail.com> writes:
I have a problem and maybe one you can explain, why this failure 
happen.
Initial situation:
I have a opengl texture and I want to copy the pixel. I store the 
original pixel in an ubyte pointer and allocate new pixel memory 
with:
ubyte[] newPixel = new ubyte[this.width * this.height * 
this.depth];
and copy the pixel with
newPixel[] = *orgPixel;
or
memcpy(&newPixel[0], orgPixel, this.width * this.height * 
this.deph);

Both compiles without errors or warnings.
But if I want to store the newPixel in a new Texture, I see only 
black, no matter what method I use.
But if I change my allocation to
ubyte* newPixel = cast(ubyte*) GC.malloc(this.width * this.height 
* this.deph * ubyte.sizeof);
and copy then with
memcpy(&newPixel[0], orgPixel, this.width * this.height * 
this.deph);

it works fine and I see the copied texture.

My question is: why? What is the difference between both ways of 
allocations?
Apr 13 2013
next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
Forget to say: Of course I use the .ptr property to load the 
newPixel into the texture, if I use the ubyte storage.
Apr 13 2013
prev sibling next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/13/2013 02:22 PM, Namespace wrote:

 I have a opengl texture and I want to copy the pixel. I store the
 original pixel in an ubyte pointer and allocate new pixel memory with:
 ubyte[] newPixel = new ubyte[this.width * this.height * this.depth];
Make sure that you really do not need to multiply that byte count with the .sizeof property of the actual value. But I guess it is fine because the elements are ubyte and ubyte.sizeof is 1.
 and copy the pixel with
 newPixel[] = *orgPixel;
That copies the first element of orgPixel to every element of newPixel. Probably not something that you want.
 or
 memcpy(&newPixel[0], orgPixel, this.width * this.height * this.deph);
That is different. Now you are copying all of the elements at orgPixel.
 Both compiles without errors or warnings.
 But if I want to store the newPixel in a new Texture, I see only black,
 no matter what method I use.
Are you sure that the memcpy method doesn't work?
 But if I change my allocation to
 ubyte* newPixel = cast(ubyte*) GC.malloc(this.width * this.height *
 this.deph * ubyte.sizeof);
 and copy then with
 memcpy(&newPixel[0], orgPixel, this.width * this.height * this.deph);

 it works fine and I see the copied texture.

 My question is: why? What is the difference between both ways of
 allocations?
Can you show two small programs that behaves differently. :) Ali
Apr 13 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Namespace:
 I have a problem and maybe one you can explain, why this 
 failure happen.
Consider using something like: auto newPixel = orgPixel[0 .. this.width * this.height * this.depth].dup; Bye, bearophile
Apr 13 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Saturday, 13 April 2013 at 22:18:21 UTC, bearophile wrote:
 Namespace:
 I have a problem and maybe one you can explain, why this 
 failure happen.
Consider using something like: auto newPixel = orgPixel[0 .. this.width * this.height * this.depth].dup; Bye, bearophile
Nice idea. That works too. Here an overview: ubyte* before = cast(ubyte*) this.getPixels(); size_t size = this.width * this.height * 4; ubyte* after = cast(ubyte*) GC.malloc(ubyte.sizeof * size); /// works //ubyte[] after = before[0 .. size].dup; /// works //ubyte[] after = new ubyte[size]; /// doesn't work memcpy(after/*.ptr*/, before, size); It's a bit strange.
Apr 13 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
It seems that no content is copied with memcpy if I allocate with 
new.
The memory is nulled.
If I allocate with GC.malloc or with .dup I get the correct 
content.
That seems like a bug. And I cannot give you an simple example 
because my code works together with derelict etc. Would be too 
much work to create an simple example.

The mysterious thing is:
I store the pixel into a file. If I store the original pixel I 
get only the correct output, if I don't use the allocations of 
newPixel with new.
If I use
ubyte[] newPixel = new ubyte[size];
The original pixel memory is nulled. That is the explanation why 
memcpy seems not to work: memcpy works but the original pixel is 
nulled so nothing is copied. But that is weird...
Apr 14 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
Maybe new allocate the original pixel memory? o.O
Apr 14 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
Hehe... I found this in my getPixel method after the allocation 
of the pixel memory:
scope(exit) delete pixels;
Do not know what I was thinking.
My fault. :)
Apr 14 2013