Page 1 of 1

STRING ARRAY size in bytes?

Posted: Thu Jun 02, 2005 11:47 pm
by holyfieldstudios
How to calculate size (in bytes) of allocated memory by string array?

Posted: Thu Jun 02, 2005 11:56 pm
by dell_jockey
from the manual:
When you define a new array, please note that it will have one more element than you used as parameter, because the numbering of the elements in PureBasic (like in other BASIC's) starts at element 0. For example when you define Dim(10) the array will have 11 elements, elements 0 to 10.
assuming that your string consists of single byte character values, the above pretty much describes what you want to know.

I dont mean lenght of array

Posted: Fri Jun 03, 2005 12:05 am
by holyfieldstudios
I dont mean lenght of array byt size in bytes of one dimensional array..
dell_jockey wrote:from the manual:
When you define a new array, please note that it will have one more element than you used as parameter, because the numbering of the elements in PureBasic (like in other BASIC's) starts at element 0. For example when you define Dim(10) the array will have 11 elements, elements 0 to 10.
assuming that your string consists of single byte character values, the above pretty much describes what you want to know.

Posted: Fri Jun 03, 2005 11:52 am
by srod
First, my little 'experiments' suggest that array dimensions are 'hard coded' into the executable; i.e. are not explicitly recorded in memory. You can see this if you declare a 2 dimensional array and then examine the assembly code generated by the compiler.

Also, there seems to be no runtime checking on array bounds since the following does not generate a runtime error, but simply crashes, or not, (depending how far out of bounds the errant index is!) Run the following without the debugger:

Code: Select all

Dim a.l(6)
a(6)=7
a(10000)=10
MessageRequester("test",Str(a(10000)), #PB_MessageRequester_Ok)
This indicates again that the array bounds are not recorded.

I then tried the following:

Code: Select all

Dim test$(1)
test$(0)="ABC"
test$(1)="DEFG"
Which generates the following assembly code:

Code: Select all

; Dim test$(1)
  PUSH   dword 8
  PUSH   dword a_test$
  PUSH   dword s_s
  MOV    ebx,4
  MOV    edx,dword [a_test$]
  CALL   SYS_FreeStringStructuredArray
  MOV    eax,2
  MOV    ebx,4
  CALL   SYS_AllocateArray
; test$(0)="ABC"
  MOV    ebp,dword [a_test$]
  MOV    edx,_S1
  LEA    ecx,[ebp]
  CALL   SYS_FastAllocateStringFree
; test$(1)="DEFG"
  MOV    edx,_S2
  LEA    ecx,[ebp+4]
  CALL   SYS_FastAllocateStringFree
This shows how pointers to the individual elements are being stored.

Basically, with a one dimensional string array, the array consists of a series of pointers to the individual strings, but again there seems to be no record of the array dimension in the final executable.

The point seems to be that you can achieve your goal, providing you know the dimensions of the underlying array beforehand. The following shows a particularly unsophisticated way of determining the amount of memory allocated for a one dimensional string array with a known number of elements:

Code: Select all

#NumElements=6

SizeOfArray = 0

Dim test$(#NumElements-1); Indexes start at zero remember!
;Initialise some data, leaving 3 elements uninitialised, just for the hell of it!
test$(0)="ABC"
test$(1)="DEFG"
test$(2)="Hello"

base_addr = test$();This is the base address of the array.
For i=0 To #NumElements-1
  addr=PeekL(base_addr+i*4);This is the address of the ith element in memory.
  If addr;Ignore unititialised elements.
    SizeOfArray + Len(PeekS((addr)))+1;Add the length of the string to the count. Add 1 for the terminating zero.
  EndIf
Next i

;Now add the amount of memory given over to the memory pointers.
SizeOfArray + 4*#NumElements
MessageRequester("Byte count", "The number of bytes used is: "+Str(SizeOfArray),  #PB_MessageRequester_Ok)
End
Hope this helps, though I must warn to not being 100% certain of the accuracy of my assertions!