B4R Question Max array size

daveinhull

Active Member
Licensed User
Longtime User
Hello,

Is there a maximin size for a byte array?
I've declared a byte array of 115200 to hold 240x240x2 byte lcd bit map
But when I try to zero it with a simple loop it errors with:
Out of bounds error. Array length = 49664, Index = 49664

Why 49664, seems a strange number?

Any advice please?
 

daveinhull

Active Member
Licensed User
Longtime User
Sorry, the question was really about whether there is a max array size, but here is the code (I'm using an ESP32C3):
B4X:
Sub Process_Globals
    Public BigArray(115200) As Byte
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Delay (1000)
    Log("AppStart")
    Log ("Test")
    For z = 0 To 115199
        BigArray (z) = 0
    Next
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Maybe you need to make 'z' a Long, I think it will default to int if unspecified.
 
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
Hi, sorry, it was defined as long, I had just deleted some log messages to tidy up the code snippet and accidentally delete the Dim for z.

Although even as an integer it should have made it 65535, but its an out of bounds error at 49664šŸ¤”
 
Upvote 0

Gerardo Tenreiro

Active Member
Licensed User
The same thing happened to me but with the FLOAT variable, the limit is 25822 TOTAL variables declared in the application, if you declare more variables an error is generated that is usually from the WIFI.H release or something else. If you search the Forum you will see my post.

In the case of Bit variables I think the limit is 108144, not one more

In Arduino there is no this limit, so in my opinion it is something internal to B4R, but at the moment I don't know more.
Luck

#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: True
#StackBufferSize: 600
#End Region
'Ctrl+Click to open the C code folder: ide://run?File=%WINDIR%\System32\explorer.exe&Args=%PROJECT%\Objects\Src

Sub Process_Globals
Public Serial1 As Serial

Public BigArray(108144) As Byte
End Sub



Private Sub AppStart
Dim z As ULong

Serial1.Initialize(115200)

Log("AppStart")



Log("AppStart")
Log ("Test")

For z = 0 To BigArray.Length - 1
BigArray (z) = 0
Next
End Sub
 
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
@Gerardo Tenreiro, thanks for your reply, whch got me thinking

I've created a small app (below) which does the same thing using Iinline C and then in B4R.
The inline C works (well no errors), but it does not work in B4R - firstly have I got the example test code right?
If I have, then why is there a different result?
The log message is
AppStart
Done in C
Out of bounds error. Array length = 49664, Index = 49664
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 600
#End Region
'Ctrl+Click to open the C code folder: ide://run?File=%WINDIR%\System32\explorer.exe&Args=%PROJECT%\Objects\Src

Sub Process_Globals
    Public Serial1 As Serial
    Public BigArray(115200) As Byte
    Public z As ULong
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Delay (3000)
    Log("AppStart")
'   
    RunNative ("LoadBigArray",Null)

    Log ("Done in C")

    For z = 0 To 115199
        BigArray (z) = 0
    Next

    Log ("Done in B4R")

End Sub

#if c
byte BigArray2[115200];

void LoadBigArray (B4R::Object* o) {
    long z = 0;
    For (z = 0; z <115199; z++) {
        BigArray2[z] = 0;
    }
};

#End If

Please can smeone help with this?
 
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
@peacemaker , thanks for the reply and I've had a look at the link and I'm asuming you mean for me to add
B4X:
Public Clear() As Byte = Array As Byte(0)
or in my case
B4X:
Public BigArray() As Byte = Array As Byte(0)
as Erel indicated(?), but this doesn't fix the problem or solve the need I have.

As I mentiuoned in the OP I need an internal array to act as a LCD buffer/bit map so I can manipulate screen bits and then send the entire screen bit map to the display in one command rather than sending each bit individually over the SPI link - its far far faster that way.

Setting everything to zero is only to flush the buffer (and to be honest to provide some code example for the problem), but then I need to be able to access any location in the 115200 array.

I really don't understand why it works in the inline C code and not it B4R and also why it errors on 49664 which appears to be some arbitary number?

Does anyone know if there is a size limit to byte arrays?

Again, much appreciate the help and if if anyone has any more thoughts or pointers I would welcome them. I really want to stick with the B4R envornment, but its just looking like it would be far easier to revert back to C in Arduino šŸ˜©
 
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
So just trying different things and decided to set #CheckArrayBounds to false, and it worksšŸ˜²šŸ¤Ŗ
The log messages are
AppStart
Done in C
Done in B4R
Big array value at 87654 is 12 <----- YES!!!!
Big array value at 115199 is 24 <----- YES!!!!
What is the purpose of the #CheckArrayBound directive??
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: False
    #StackBufferSize: 600
#End Region
'Ctrl+Click to open the C code folder: ide://run?File=%WINDIR%\System32\explorer.exe&Args=%PROJECT%\Objects\Src

Sub Process_Globals
    Public Serial1 As Serial
    Public BigArray(115200) As Byte
    Public z As ULong
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Delay (3000)
    Log("AppStart")
    RunNative ("LoadBigArray",Null)
    Log ("Done in C")
    For z = 0 To 115199
        BigArray (z) = 0
    Next
    Log ("Done in B4R")
    BigArray(87654) = 12
    Log ("Big array value at 87654 is ",BigArray(87654))
    BigArray(115199) = 24
    Log ("Big array value at 115199 is ",BigArray(115199))
End Sub
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
@peacemaker, but what's confusing me is that a) it works perfectly in the online C code and in the Arduino IDE and b) it works if I switch of the CheckArrayBounds attribute???

So got the test program to work and moved back to my graphics test program. The big array now works, SPI.transfer(data,SizeOf(data)) still only transfer part of the array, actually only (guess what) 49664 - why this number, its not even a power of 2?
B4X:
Private Sub GC9A01_spi_tx (data() As Byte)
    Log (SizeOf(data)) ' <--- this returns 49664
    SPI.transfer(data,SizeOf(data))
End Sub
the SPI .transfer rouinte is devclared as:
transfer (data() As Byte, size As ULong) As Void

This has got to be a B4R problem?
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
No idea, i'm not an expert in Arduino and C-code.
Does Inline-C code work OK with #CheckArrayBounds = true ?
But if false ?
 
Last edited:
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
@peacemaker, yes it works either way.

As I mentined, it must be a problem in B4R because:
1) the whole graphc program works perfectly on the device, so it can't be any limitaitn of the ESP32C3, from the Arduino IDE include use of the big array
2) there is no problem with the big array in the inline C code with or without #CheckArrayBounds = true or false, but I'd expect that as the inline code will just be being sent straight through to the C compiler
3) the out of bound happens at an arnbitary number 49664 (unless there is some meaning to this number) and with #CheckArrayBounds = false, the big array referencing works, but SizeOf doesn't work, i.e.
B4X:
Public BigArray[115200] as Byte
...
...
...
BigArray[115199] = 123
Log (BigArray[115199]) ' <--- logs 123, so the array must be that big
Log (SizeOf (BigArray)) '<--- logs 49664!!! '

If I'm doing something wrong I'd like to find out as I'm spending hours trying to do this, and if there is simply a limit to the array size or if there is actually a bug in B4R, then I'd just like to know so I can just do this app in C (and to save my sanity as well šŸ¤Ŗ)

Thanks for your support.
Dave
 
Upvote 0

Gerardo Tenreiro

Active Member
Licensed User
Hello, I copied your code directly to B4R and it gave me an error with "#CheckArrayBounds: False"
I attach an image
I know this doesn't help, but I just want to follow your steps and verify what you are doing to see that it is not a problem with your installation or mine.
Can you verify and comment?
thank you

#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: False
#StackBufferSize: 600
#End Region
'Ctrl+Click to open the C code folder: ide://run?File=%WINDIR%\System32\explorer.exe&Args=%PROJECT%\Objects\Src

Sub Process_Globals
Public Serial1 As Serial
Public BigArray(115200) As Byte
Public z As ULong
End Sub

Private Sub AppStart
Serial1.Initialize(115200)
Delay (3000)
Log("AppStart")
RunNative ("LoadBigArray",Null)
Log ("Done in C")
For z = 0 To BigArray.Length - 1
BigArray(z) = 0
Next
Log ("Done in B4R")
BigArray(87654) = 12
Log ("Big array value at 87654 is ",BigArray(87654))
BigArray(115199) = 24
Log ("Big array value at 115199 is ",BigArray(115199))
End Sub

1701627935321.png
 
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
@Gerardo Tenreiro, are you missing the inline C code after the AppStart routine, after "End Sub"
B4X:
#if c

void LoadBigArray (B4R::Object* o)
{
    byte BigArray2[115200];
    long z;
    for (z = 0; z < 115199; z++)
    {
        BigArray2[z] = 0;
    }
};

#End If
 
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
I also added another test:
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: False
    #StackBufferSize: 600
#End Region
'Ctrl+Click to open the C code folder: ide://run?File=%WINDIR%\System32\explorer.exe&Args=%PROJECT%\Objects\Src

Sub Process_Globals
    Public Serial1 As Serial
    Public BigArray(115200) As Byte
    Public z As ULong
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Delay (3000)
    Log("AppStart")
'   
    RunNative ("LoadBigArray",Null)
    Log ("Done in C")
    For z = 0 To 115199
        BigArray (z) = 0
    Next
    Log ("Done in B4R")
    BigArray(87654) = 12
    Log ("Big array value at 87654 is ",BigArray(87654))
    BigArray(115199) = 24
    Log ("Big array value at 115199 is ",BigArray(115199))
    Log ("SizeOf BigArray is ", SizeOf(BigArray))
End Sub

#if c

void LoadBigArray (B4R::Object* o)
{
    byte BigArray2[115200];
    long z;
    for (z = 0; z < 115199; z++)
    {
        BigArray2[z] = 0;
    }
};

#End If
 
Upvote 0

Gerardo Tenreiro

Active Member
Licensed User
Good morning
Even including the code in "C" at the end an error is generated
I copy the code that I sent as is and paste it into B4R.
Are you sure it doesn't generate the error for you?

#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: False
#StackBufferSize: 600
#End Region
'Ctrl+Click to open the C code folder: ide://run?File=%WINDIR%\System32\explorer.exe&Args=%PROJECT%\Objects\Src

Sub Process_Globals
Public Serial1 As Serial
Public BigArray(115200) As Byte
Public z As ULong
End Sub

Private Sub AppStart
Serial1.Initialize(115200)
Delay (3000)
Log("AppStart")
'
RunNative ("LoadBigArray",Null)
Log ("Done in C")
For z = 0 To 115199
BigArray (z) = 0
Next
Log ("Done in B4R")
BigArray(87654) = 12
Log ("Big array value at 87654 is ",BigArray(87654))
BigArray(115199) = 24
Log ("Big array value at 115199 is ",BigArray(115199))
Log ("SizeOf BigArray is ", SizeOf(BigArray))
End Sub

#if c

void LoadBigArray (B4R::Object* o)
{
byte BigArray2[115200];
long z;
for (z = 0; z < 115199; z++)
{
BigArray2[z] = 0;
}
};

#End If

1701679028251.png
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
paste it into B4R
i also tried with my ESP32 - the same errors at any #CheckArrayBounds value.

Public BigArray(101200) As Byte - works, but 102200 - already does not work :)
But C-code is always working
 
Last edited:
Upvote 0

daveinhull

Active Member
Licensed User
Longtime User
Good morning @Gerardo Tenreiro , firstly, thanks for helping inthe testing of this issue.

Yes it works perfectly for me and gives the following log message:
AppStart
Done in C
Done in B4R
12
24
49664

I'm using the ESP32C3 device.

Thanks
Dave
 
Upvote 0
Top