Chris Angelico <ros...@gmail.com> Wrote in message: > 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). >
Array size is inside the malloc block, but outside the struct block. As you can see if you try to delete without the brackets when you used new [], some runtimes will crash. This is not to say that there will always be these extra offsets, just that they can be there. -- DaveA -- https://mail.python.org/mailman/listinfo/python-list