Page 1 of 2
Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 12:02 pm
by infratec
Hi,
since I want to optimize the code from doctorized, I need something like this:
Code: Select all
Structure MIB_IFROW
dwIndex.l
EndStructure
Structure MIB_IFTABLE1
dwNumEntries.l
*table.MIB_IFROW[0]
EndStructure
Define MIBIfTable.MIB_IFTABLE1
If I do this, I can do
Code: Select all
MIBIfTable\table = AllocateMemory(SizeOf(MIB_IFROW) * 2)
and also
But SizeOf(MIB_IFTABLE1) returns 4 and not 8.
I think that's strange.
Complete code:
Code: Select all
Structure MIB_IFROW
dwIndex.l
EndStructure
Structure MIB_IFTABLE1
dwNumEntries.l
*table.MIB_IFROW[0]
EndStructure
Define MIBIfTable.MIB_IFTABLE1
Debug SizeOf(MIB_IFTABLE1)
MIBIfTable\table = AllocateMemory(SizeOf(MIB_IFROW) * 2)
ShowMemoryViewer(@MIBIfTable, SizeOf(MIBIfTable))
MIBIfTable\table[1]\dwIndex = 88
Debug MIBIfTable\table[1]\dwIndex
But if I implement this in the original code the program hangs inside the API call wich uses this structure.
I use PB 5.30 x86.
Is there an other trick
Bernd
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 1:49 pm
by Little John
infratec wrote:But SizeOf(MIB_IFTABLE1) returns 4 and not 8.
I think that's strange.
IMHO this is a bug in PB.
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 2:42 pm
by auser
I don't see a bug here (except probably that PB allows creation of an static array with 0 size without warning).
Code: Select all
Structure MIB_IFROW
dwIndex.l
EndStructure
Structure MIB_IFTABLE1
dwNumEntries.l
*table.MIB_IFROW[2]
EndStructure
Define MIBIfTable.MIB_IFTABLE1
Debug SizeOf(MIB_IFTABLE1)
MIBIfTable\table[0] = AllocateMemory(SizeOf(MIB_IFROW))
MIBIfTable\table[1] = AllocateMemory(SizeOf(MIB_IFROW))
ShowMemoryViewer(@MIBIfTable, SizeOf(MIBIfTable))
MIBIfTable\table[1]\dwIndex = 88
Debug MIBIfTable\table[1]\dwIndex
Code: Select all
Structure dummy
somelong.l
somestring.s
somethingelse.i
EndStructure
Structure test_1
somelong.l
char.a[0]
EndStructure
Debug(SizeOf(test_1))
; somelong = 4 bytes (type long)
; char.a[?] = crap ...because it's an array with 0 itmes of type a
; -----------------------
; PB says: 4 bytes
Structure test_2
somelong.l
char.a[2]
EndStructure
Debug(SizeOf(test_2))
; somelong = 4 bytes (type long)
; char.a[0] = 1 byte (type a)
; char.a[1] = 1 byte (type a)
; -----------------------
; PB says: 6 bytes
Structure test_3
somelong.l
*char.dummy[0]
EndStructure
Debug(SizeOf(test_3))
; somelong = 4 bytes
; *char.dummy[?] = crap ...because it's an array with 0 items of type pointer to structure of type dummy
; -----------------------
; PB says: 4 bytes
Structure test_4
somelong.l
*char.dummy[2]
EndStructure
Debug(SizeOf(test_4))
; somelong = 4 bytes (type long)
; *char.dummy[0] = 4 bytes (type pointer to structure of type dummy)
; *char.dummy[1] = 4 bytes (type pointer to structure of type dummy)
; -----------------------
; PB says: 12 bytes
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 2:59 pm
by luis
auser wrote:I don't see a bug here (except probably that PB allows creation of an static array with 0 size without warning).
In PB something like this
is legal to be able to easily overlap the structure to a memory area with a size equal n times SizeOf(Integer)
a.i[1] would make the structure 4 bytes wide on x86 (one array element at 0), a.i[2] would make it 8 bytes wide (elements at 0 and 1) and so on, but a.i[0] doesn't mean anything as you noted unless you introduce the special meaning supported by PB in this specific case, kind of placeholder with an unknown max index.
Code: Select all
Dim mem(2)
mem(0) = 123
mem(1) = 124
mem(2) = 125
Structure foo
a.i[0]
EndStructure
Define *p.foo = @mem(0)
Debug *p\a[0]
Debug *p\a[1]
Debug *p\a[2]
Structure bar
a.i[1]
EndStructure
Debug SizeOf(bar) ; this is 4
Debug SizeOf(foo) ; this is 0, and in fact it's more an "unknown" than anything else
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 3:03 pm
by graph100
This should be in the help of PureBasic.
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 3:24 pm
by infratec
Hi,
is not an array with size 0, it is a pointer.
So I expected that the pointer is available, even when the size of the array is 0.
I can only work around with an extra pointer in a struct:
Code: Select all
Structure MIB_IFROW
dwIndex.l
EndStructure
Structure MIB_IFTABLE1
dwNumEntries.l
*table
EndStructure
Structure Test
table.MIB_IFROW[0]
EndStructure
Define MIBIfTable.MIB_IFTABLE1
Define *Ptr.Test
Debug SizeOf(MIB_IFTABLE1)
MIBIfTable\table = AllocateMemory(SizeOf(MIB_IFROW) * 2)
*Ptr = MIBIfTable\table
ShowMemoryViewer(@MIBIfTable, SizeOf(MIBIfTable))
*Ptr\table[1]\dwIndex = 88
Debug *Ptr\table[1]\dwIndex
But than the access looks not like it should
Bernd
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 3:31 pm
by luis
infratec wrote:Hi,
is not an array with size 0, it is a pointer.
No, it's an array of structured pointers with size 0.
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 3:34 pm
by infratec
But even with my workaround from above, the API call hangs.
I think he needs the memory at the position of the pointer and no pointer.
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 3:52 pm
by luis
Sorry, don't see any api call, I can only reply about the "strangeness" of the sizeof(), it's indeed strange but it's consistent with the example above (it's a static array with size 0).
Maybe the choice of not occupying space at all inside the structure can be debatable, I'm not sure.
But in reality it does not exist until you overlap it to something, while an empty pointer exists even when not initialized.
Using a pointer for this kind array is indeed strange.
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 3:58 pm
by auser
I did not know that that memory-overlap is supported. I'm not really sure what you need exactly. If you don't need pointer why you don't use just table.MIB_IFROW[2] afterwards? Maybe you could try this:
Code: Select all
Structure MIB_IFROW
dwIndex.l
EndStructure
Structure MIB_IFTABLE1
dwNumEntries.l
table.MIB_IFROW[0]
EndStructure
Define MIBIfTable.MIB_IFTABLE1
Debug SizeOf(MIB_IFTABLE1)
PokeI(@MIBIfTable+4,AllocateMemory(SizeOf(MIB_IFROW) * 2))
ShowMemoryViewer(@MIBIfTable, SizeOf(MIBIfTable))
MIBIfTable\table[1]\dwIndex = 88
Debug MIBIfTable\table[1]\dwIndex
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 4:25 pm
by infratec
Hi,
it's for this:
http://www.purebasic.fr/english/viewtop ... 28#p451528
The API call is:
Code: Select all
...
lSize = 0
lErrors = GetIfTable_(@MIB_IFTABLE, @lSize, 0)
; If lErrors = 122
; Debug lSize - SizeOf(LONG)
; *MIB_IFTABLE = AllocateMemory(lSize - SizeOf(LONG) - SizeOf(Integer))
; MIB_IFTABLE\table = @*MIB_IFTABLE
; Debug MIB_IFTABLE\table
; EndIf
;lSize = SizeOf(MIB_IFTABLE1)
lErrors = GetIfTable_(@MIB_IFTABLE, @lSize, 0)
Debug MIB_IFTABLE\dwNumEntries
...
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 4:48 pm
by auser
The MIB_IFROW structure looks pretty different to the version you've posted in your example:
http://msdn.microsoft.com/en-us/library ... 85%29.aspx ...and it looks like pdwSize is telling you the size of the buffer anyway. So I think you could just give it an pointer to a buffer with one item of MIB_IFROW table[1] as first try and do some AllocateMemory afterwards. Maybe it's easier to just use some *void = AllocateMemory(return_size_of_pdwSize) and give it again to the API-function and finally do some *mystruc.MIB_IFTABLE = *void to give it some structure afterwards.
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 6:20 pm
by infratec
@ausser
Here in my example I shortened the structure a bit
It was only to demonstrate the problem.
This saved minimum 1 page of this thread.
Yes, I think also that the best is to allocate a buffer and afterwords place a pointer with the structure over it.
But still I have the problem that there is an array of an unkown size inside the struct.
Ok, I can set the pointer manually to the next entry.
But since I'm lazy and PB should be able to handle this, I searched for a 'better' solution.
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 7:54 pm
by Little John
luis wrote:infratec wrote:Hi,
is not an array with size 0, it is a pointer.
No, it's an array of structured pointers with size 0.
I also thought that it is a pointer to an array, rather than an array of pointers.
Thanks for the clarification, Luis!
Re: Pointer to an array inside of a structure
Posted: Thu Aug 21, 2014 10:46 pm
by idle
think you just need to do this
Code: Select all
Structure MIB_IFROW_STRUCT
wszName.u[#MAX_INTERFACE_NAME_LEN];
dwIndex.l;
dwType.l;
;...
EndStructure
Structure MIB_IFROW
Row.MIB_IFROW_STRUCT[0] ;access the memory with the pattern of the structure, has no size it's just a pattern
EndStructure
Structure MIB_IFTABLE1
dwNumEntries.l
*table.MIB_IFROW ;<- pointer to the access pattern
EndStructure
MIB_IFTABLE.MIB_IFTABLE1 ;< define a var or pointer
MIB_IFTABLE\table = AllocateMemory(Size) ;or size * sizeof(MIB_IFROW_STRUCT)
MIB_IFTABLE\table\Row[0]\dwIndex ;access the array of MIB_IFROW_STRUCT