Jump to content

  • Log In with Google      Sign In   
  • Create Account


We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.

Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


Member Since 25 Mar 2009
Offline Last Active May 22 2013 08:43 AM

Topics I've Started

pool allocator

26 September 2012 - 06:29 AM

Hello again, I have another query about custom allocators.

I've read that allocators of the same type are required by the standard to be able to
deallocate the memory that another of its type has allocated. This presents a problem when trying to implement
a memory pool based allocator (or variation thereof) seeing as I would like each pool allocator to manage its own
memory block, the size of which supplied by a template parameter. Something along the lines of

template <typename T, std::size_t Blocks>
class pool_allocator ;

But of course allocators of the same type would not be able to deallocate memory of other instances of the same
type of pool class.

I decided try and make the data members static, _blocks, and _size for now since I haven't really fleshed out how this is going to work. and then do something like this:

inline pool_allocator( ) noexcept {
	T* __Tmp = reinterpret_cast<T*>(::operator new((Blocks + _size) * sizeof(T)));
	std::uninitialized_copy(_blocks, _blocks+_size, __Tmp); // may not be necessary because most pools will be constructed at the beginning of the program, but it doesn't hurt runtime to have it in there if this is the case.
	_blocks = __Tmp;
	_size += Blocks;

// ...
// static member initialization
template <typename T, std::size_t Blocks> T* pool_allocator<T, Blocks>::_blocks = nullptr;
template <typename T, std::size_t Blocks> std::size_t pool_allocator<T, Blocks>::_size = 0;

It would be better if I could get the summation of all pool allocator Blocks at compile time but I see no way to do this at the moment - ideas anyone?


There was something else I wanted to say as well but it escapes me at the moment.. It'll come back.
Anyway, how would I deal with fragmentation in the most efficient manor possible while still maintaining contiguous blocks of memory that arrays allow for? some things may be deallocated from the middle of the memory block and the only way I can see is to keep a sort of queue of pointers to free space in memory but this is a terrible solution for obvious reasons.

I'm not entirely sure my approach will work in the end, but there is little to go by on the internet that I've found

custom allocator adapter

24 September 2012 - 12:50 PM

Hi, so as a little excersize I've been looking into c++ allocators a little more and google'd my way to the link below (which I've come across a couple times but never really bothered to dig into it)


Something that peaked my interest was the simple memory profiling with the tracking policy class, so I decided to implement something similar to this but instead of using policy classes I went the adapter route. Use of my class goes something like this:
#include "allocator.hpp" // my own allocator header
// ...
std::vector<int, tracking<std::allocator<int>>> vec;
// ...
std::cout << vec.get_allocator( ).total_allocations( ) << std::endl;
// etc. etc..

However this code produces an ungodly amount of errors during compilation, after taking a look it seems that the standard library that comes with gcc at least uses something along the lines of std::allocator_traits<tracking<int>> internally which of course is not what I want.

Is there any way to get around this? I don't understand why int is being passed to tracking in its template parameters, or even how since wouldn't it make more sense to do something like: std::allocator_traits<Allocator>::??? which as far as I can see would work.. I could try the policy based approach but I expect this would fail too unless I have my allocator defined with a default policy or something..

Maybe I will just roll my own containers that mimic the standard. Though as of right now it seems overkill (although fun) just for this tiny error.


MinGW 4.7.1 GDB disassembly output

01 September 2012 - 12:40 PM

Hello all, quick question for those that are intimately familiar with disassembling c++ programs (I for one am not, though would like to be)

I wrote a few simple programs to test gdb and its disassemble command and noticed that for one of programs the output seemed a bit verbose. Here is the two programs with assembly output attached.

#include <iostream>
#include "math.hpp"
int main(int, char**)
std::cout << math::sign(1) << std::endl;
return 0;

Dump of assembler code for function main(int, char**):
   0x0000000000401500 <+0>: push   %rbp
   0x0000000000401501 <+1>: push   %r15
   0x0000000000401503 <+3>: push   %r14
   0x0000000000401505 <+5>: push   %r13
   0x0000000000401507 <+7>: push   %r12
   0x0000000000401509 <+9>: push   %rdi
   0x000000000040150a <+10>: push   %rsi
   0x000000000040150b <+11>: push   %rbx
   0x000000000040150c <+12>: sub    $0x148,%rsp
   0x0000000000401513 <+19>: lea    0x80(%rsp),%rbp
   0x000000000040151b <+27>: movaps %xmm6,0x20(%rbp)
   0x000000000040151f <+31>: movaps %xmm7,0x30(%rbp)
   0x0000000000401523 <+35>: movaps %xmm8,0x40(%rbp)
   0x0000000000401528 <+40>: movaps %xmm9,0x50(%rbp)
   0x000000000040152d <+45>: movaps %xmm10,0x60(%rbp)
   0x0000000000401532 <+50>: movaps %xmm11,0x70(%rbp)
   0x0000000000401537 <+55>: movaps %xmm12,0x80(%rbp)
   0x000000000040153f <+63>: movaps %xmm13,0x90(%rbp)
   0x0000000000401547 <+71>: movaps %xmm14,0xa0(%rbp)
   0x000000000040154f <+79>: movaps %xmm15,0xb0(%rbp)
   0x0000000000401557 <+87>: mov    %ecx,0x110(%rbp)
   0x000000000040155d <+93>: mov    %rdx,0x118(%rbp)
   0x0000000000401564 <+100>: lea    0x1b15(%rip),%rax	    # 0x403080 <__gxx_personality_sj0>
   0x000000000040156b <+107>: mov    %rax,-0x30(%rbp)
   0x000000000040156f <+111>: lea    0x9faa(%rip),%rax	    # 0x40b520 <___DTOR_LIST__+16>
   0x0000000000401576 <+118>: mov    %rax,-0x28(%rbp)
   0x000000000040157a <+122>: lea    -0x20(%rbp),%rax
   0x000000000040157e <+126>: lea    0x20(%rbp),%rdx
   0x0000000000401582 <+130>: mov    %rdx,(%rax)
   0x0000000000401585 <+133>: lea    0x5a(%rip),%rdx	    # 0x4015e6 <__fu0__ZSt4cout+34>
   0x000000000040158c <+140>: mov    %rdx,0x8(%rax)
   0x0000000000401590 <+144>: mov    %rsp,0x10(%rax)
   0x0000000000401594 <+148>: lea    -0x60(%rbp),%rax
   0x0000000000401598 <+152>: mov    %rax,%rcx
   0x000000000040159b <+155>: callq  0x404880 <_Unwind_SjLj_Register>
   0x00000000004015a0 <+160>: callq  0x4042f0 <__main>
   0x00000000004015a5 <+165>: movl   $0x1,0x1c(%rbp)
   0x00000000004015ac <+172>: lea    0x1c(%rbp),%rax
   0x00000000004015b0 <+176>: mov    %rax,%rcx
   0x00000000004015b3 <+179>: callq  0x409ad0 <math::sign<int>(int const&)>
   0x00000000004015b8 <+184>: movl   $0x1,-0x58(%rbp)
   0x00000000004015bf <+191>: mov    %eax,%edx
   0x00000000004015c1 <+193>: lea    0x110cc(%rip),%rcx	    # 0x412694 <__imp__ZSt4cout>
   0x00000000004015c8 <+4>: callq  0x403090 <_ZNSolsEi>
   0x00000000004015cd <+9>: lea    0x1ab4(%rip),%rdx	    # 0x403088 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_>
   0x00000000004015d4 <+16>: mov    %rax,%rcx
   0x00000000004015d7 <+19>: callq  0x403098 <_ZNSolsEPFRSoS_E>
   0x00000000004015dc <+24>: mov    $0x0,%eax
   0x00000000004015e1 <+29>: mov    %eax,0xc(%rbp)
   0x00000000004015e4 <+32>: jmp    0x4015fd <__fu0__ZSt4cout+57>
   0x00000000004015e6 <+34>: lea    -0x20(%rbp),%rbp
   0x00000000004015ea <+38>: mov    -0x50(%rbp),%rax
   0x00000000004015ee <+42>: movl   $0xffffffff,-0x58(%rbp)
   0x00000000004015f5 <+49>: mov    %rax,%rcx
   0x00000000004015f8 <+52>: callq  0x404c40 <_Unwind_SjLj_Resume>
   0x00000000004015fd <+57>: lea    -0x60(%rbp),%rax
   0x0000000000401601 <+61>: mov    %rax,%rcx
   0x0000000000401604 <+64>: callq  0x4048e0 <_Unwind_SjLj_Unregister>
   0x0000000000401609 <+69>: mov    0xc(%rbp),%eax
   0x000000000040160c <+72>: movaps 0x20(%rbp),%xmm6
   0x0000000000401610 <+76>: movaps 0x30(%rbp),%xmm7
   0x0000000000401614 <+80>: movaps 0x40(%rbp),%xmm8
   0x0000000000401619 <+85>: movaps 0x50(%rbp),%xmm9
   0x000000000040161e <+90>: movaps 0x60(%rbp),%xmm10
   0x0000000000401623 <+95>: movaps 0x70(%rbp),%xmm11
   0x0000000000401628 <+100>: movaps 0x80(%rbp),%xmm12
   0x0000000000401630 <+108>: movaps 0x90(%rbp),%xmm13
   0x0000000000401638 <+116>: movaps 0xa0(%rbp),%xmm14
   0x0000000000401640 <+124>: movaps 0xb0(%rbp),%xmm15
   0x0000000000401648 <+132>: add    $0x148,%rsp
   0x000000000040164f <+139>: pop    %rbx
   0x0000000000401650 <+140>: pop    %rsi
   0x0000000000401651 <+141>: pop    %rdi
   0x0000000000401652 <+142>: pop    %r12
   0x0000000000401654 <+144>: pop    %r13
   0x0000000000401656 <+146>: pop    %r14
   0x0000000000401658 <+148>: pop    %r15
   0x000000000040165a <+150>: pop    %rbp
   0x000000000040165b <+151>: retq  
End of assembler dump.

#include <iostream>
#include "math.hpp"
int main(int, char**)
int x = math::sign(1);
std::cout << x << std::endl;
return 0;
Dump of assembler code for function main(int, char**):
   0x0000000000401500 <+0>: push   %rbp
   0x0000000000401501 <+1>: mov    %rsp,%rbp
   0x0000000000401504 <+4>: sub    $0x30,%rsp
   0x0000000000401508 <+8>: mov    %ecx,0x10(%rbp)
   0x000000000040150b <+11>: mov    %rdx,0x18(%rbp)
   0x000000000040150f <+15>: callq  0x4041e0 <__main>
   0x0000000000401514 <+20>: movl   $0x1,-0x8(%rbp)
   0x000000000040151b <+27>: lea    -0x8(%rbp),%rax
   0x000000000040151f <+31>: mov    %rax,%rcx
   0x0000000000401522 <+34>: callq  0x4099c0 <math::sign<int>(int const&)>
   0x0000000000401527 <+39>: mov    %eax,-0x4(%rbp)
   0x000000000040152a <+42>: mov    -0x4(%rbp),%eax
   0x000000000040152d <+45>: mov    %eax,%edx
   0x000000000040152f <+47>: lea    0x1115e(%rip),%rcx	    # 0x412694 <__imp__ZSt4cout>
   0x0000000000401536 <+4>: callq  0x402f78 <_ZNSolsEi>
   0x000000000040153b <+9>: lea    0x1a2e(%rip),%rdx	    # 0x402f70 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_>
   0x0000000000401542 <+16>: mov    %rax,%rcx
   0x0000000000401545 <+19>: callq  0x402f80 <_ZNSolsEPFRSoS_E>
   0x000000000040154a <+24>: mov    $0x0,%eax
   0x000000000040154f <+29>: add    $0x30,%rsp
   0x0000000000401553 <+33>: pop    %rbp
   0x0000000000401554 <+34>: retq 
End of assembler dump.

So basically I am confused as to why using a temporary variable in this case produces less assembly code?
If any more information is needed please don't hesitate to ask :)


std::enable_if, template specialization

30 August 2012 - 04:34 PM

Hello all, been a while since I've posted here.
I've run into a problem for which my google-fu is not strong enough. Posted Image

I am attempting to tighten some of my own template library code using the std::enable_if and others
within the <type_traits> header, here is a hypothetical (cut-down) situation below.

// firstsomething.hpp
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type func(const T& x) noexcept
{ return /* something */ }

// something.hpp
template <> typename std::enable_if<true, mytype>::type func(const mytype& x) noexcept;

// something.cpp
template <> typename std::enable_if<true, mytype>::type func(const mytype& x) noexcept
{ return /* return other something */ }

Now, without the std::enable_if stuff and were I to replace this with just the bare types, the tests compiled and ran fine on GCC 4.7.1. However now I am having to wrestle with

error: template-id 'func<>' for 'std::enable_if<true, mytype>::type func(const mytype& x)' does not match any template declaration

So, where am I going wrong basically? Posted Image

I did add 'template <typename T>' to the specializations instead of 'template <>' but doesn't this then mean the functions are no longer specializations of the original?


Android Bitmap Quality

11 July 2012 - 09:56 AM

Hi all, recently I've been trying my hand at some Java and Android development.
However, no matter what I try I just can't seem to get a level of image quality that I would be happy with for the sprites in the game.

I've had issues with banding showing with subtle colour transitions on background images and imprecise pixel positioning on both my android device and emulator.. below is an image compared with the original that demonstrates what I mean (though in this case the banding isn't so bad).

Posted Image

There seems to be some sort of filtering and and scaling going on which apparently I have no control over (which is why I'm here Posted Image)
So, has anyone come across this kind of issue before and how did you fix it? [code below]

import android.view.View;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
public class MainActivity extends Activity
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState)
setContentView(new DrawView(this));

public class DrawView extends View
private Paint mpaint = new Paint( );
private Bitmap mbitmap;

public DrawView(Context context)

BitmapFactory.Options options = new BitmapFactory.Options( );
options.inDither = false;

mbitmap = BitmapFactory.decodeResource(context.getResources( ), R.drawable.box);

protected void onDraw(Canvas canvas)
canvas.drawBitmap(mbitmap, 6, 6, mpaint);


PS: I also tried SurfaceView, same problems.. I know it is somehow possible to get decent pixel quality in android, just take a look at Zenonia (my images look like those from Zenonia 1 at the moment, I would like the quality achieved in Zenonia 3/4 Posted Image )

EDIT2: Some more evidence of the problem I'm having, definitely some unwanted scaling going on. I've tried putting the image in all drawable folders one at a time, hdpi scales down and mdpi scales to what you see in the image below:

Posted Image
The Image to the right is the one I am drawing and the one on the left is from the API demos.
I can't see what I'm doing wrong, I checked the code both are being loaded via the openRawResource( ) and the decodeStream( ) methods.
There is also no evidence of scaling the frog in the API demo.. two simple lines that I have included plus the line to draw is all I can find.