Thread overview
Different behaviour of new and malloc
Apr 13, 2013
Namespace
Apr 13, 2013
Namespace
Apr 13, 2013
Ali Çehreli
Apr 13, 2013
bearophile
Apr 13, 2013
Namespace
Apr 14, 2013
Namespace
Apr 14, 2013
Namespace
Apr 14, 2013
Namespace
April 13, 2013
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?
April 13, 2013
Forget to say: Of course I use the .ptr property to load the newPixel into the texture, if I use the ubyte storage.
April 13, 2013
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

April 13, 2013
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
April 13, 2013
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.
April 14, 2013
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...
April 14, 2013
Maybe new allocate the original pixel memory? o.O
April 14, 2013
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. :)