Pointer to an array inside of a structure

Just starting out? Need help? Post your questions and find answers here.
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Pointer to an array inside of a structure

Post 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

Code: Select all

Debug MIBIfTable\table[1]\dwIndex
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
Little John
Addict
Addict
Posts: 4775
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Pointer to an array inside of a structure

Post 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.
auser
Enthusiast
Enthusiast
Posts: 195
Joined: Wed Sep 06, 2006 6:59 am

Re: Pointer to an array inside of a structure

Post 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
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Pointer to an array inside of a structure

Post 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

Code: Select all

Structure foo
 a.i[0]
EndStructure 
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
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
graph100
Enthusiast
Enthusiast
Posts: 115
Joined: Tue Aug 10, 2010 3:17 pm

Re: Pointer to an array inside of a structure

Post by graph100 »

This should be in the help of PureBasic.
_________________________________________________
My Website : CeriseCode (Warning : perpetual changes & not completed ;))
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Pointer to an array inside of a structure

Post by infratec »

Hi,

Code: Select all

*table.MIB_IFROW[0]
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 :cry:

Bernd
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Pointer to an array inside of a structure

Post 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.
"Have you tried turning it off and on again ?"
A little PureBasic review
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Pointer to an array inside of a structure

Post 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.
User avatar
luis
Addict
Addict
Posts: 3893
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Pointer to an array inside of a structure

Post 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.
Last edited by luis on Thu Aug 21, 2014 4:00 pm, edited 1 time in total.
"Have you tried turning it off and on again ?"
A little PureBasic review
auser
Enthusiast
Enthusiast
Posts: 195
Joined: Wed Sep 06, 2006 6:59 am

Re: Pointer to an array inside of a structure

Post 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
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Pointer to an array inside of a structure

Post 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

...
auser
Enthusiast
Enthusiast
Posts: 195
Joined: Wed Sep 06, 2006 6:59 am

Re: Pointer to an array inside of a structure

Post 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.
infratec
Always Here
Always Here
Posts: 7576
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Pointer to an array inside of a structure

Post by infratec »

@ausser

Here in my example I shortened the structure a bit :mrgreen:
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.
Little John
Addict
Addict
Posts: 4775
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Pointer to an array inside of a structure

Post 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. :oops:
Thanks for the clarification, Luis!
User avatar
idle
Always Here
Always Here
Posts: 5835
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Pointer to an array inside of a structure

Post 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 


Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply