On Mon, Mar 3, 2014 at 12:22 AM, Dave Angel <da...@davea.name> wrote: > Sure, for some definition of "usable". Overhead such as block > size, freelist pointer etc., are obviously outside of the > returned block. But the array size that's specified in a call to > new [], and the vptr, are definitely inside the malloc'ed block, > and may be before the struct data.
Hmm. Last I was working with it, the array size to new[] was outside the block, just as the block size to malloc(). The vptr is part of any struct/class with virtual functions, and effectively acts as a hidden class member, so you get one of those inside the block, and it's included in sizeof. //Allocated Space: The Final Frontier! #include <stdio.h> //cout sucks :) class Foo { int x; int y; int z; }; class Bar { int x; int y; int z; virtual int get_x() {return x;} }; int main() { printf("sizeof(int) = %u\n",sizeof(int)); printf("sizeof(int*) = %u\n",sizeof(int*)); printf("sizeof(Foo) = %u\n",sizeof(Foo)); printf("sizeof(Bar) = %u\n",sizeof(Bar)); Foo *foo = new Foo[10]; printf("foo = %p/%p = %u\n",foo,foo+10,(char *)(foo+10)-(char *)foo); Bar *bar = new Bar[10]; printf("bar = %p/%p = %u\n",bar,bar+10,(char *)(bar+10)-(char *)bar); return 0; } rosuav@sikorsky:~$ g++ frontier.cpp && ./a.out sizeof(int) = 4 sizeof(int*) = 8 sizeof(Foo) = 12 sizeof(Bar) = 24 foo = 0xf38010/0xf38088 = 120 bar = 0xf38090/0xf38180 = 240 The rules of structs are that they be contiguous, that they be laid out sequentially, and that any padding needed between structures is at the end of the previous one (which is why three of 4 bytes makes 12 bytes, but three of 4 bytes plus 8 bytes makes 24 - the eight-byte pointer has to be aligned on a multiple of eight bytes, so having a 20-byte structure that starts with an 8-byte pointer is a no-no). The allocated block of memory is, by definition, the same as the pointer to its first element. As it happens, the pointer bar is not synonymous with &bar->x, &bar->y, or &bar->z, which means the vptr is at the beginning of bar, which makes sense; but the compiler's not obliged to do that, and in some cases may choose not to - for instance, if bar (with a virtual function) inherited from foo (with none), it might be convenient to allow a pointer-cast to not change the value of the pointer. (g++ 4.7.2 still puts the vptr at the beginning of bar in that case, but other compilers or other versions may differ.) Array size is outside the block, presumably before it, as &foo[0] is by definition identical to foo, and there's no room inside the structure for any spare data. Virtual function table is inside the block because it's a hidden member of the object (like __class__ in Python, only better hidden). ChrisA -- https://mail.python.org/mailman/listinfo/python-list