[solved] "redim preserve" crashes PROG. (FB 1.03.0-64)

General FreeBASIC programming questions.
Post Reply
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

[solved] "redim preserve" crashes PROG. (FB 1.03.0-64)

Post by MrSwiss »

Hello all,

When using redim preserve to extend an existing String-Array (append a NEW string at the end), this crashes the program, as soon as more than ca. 5 times called.
Using the same code with a fix-len String-Array (without any redim) everything seems OK.

pseudo code:

Code: Select all

Dim shared as String fileread(1 to 1)
Dim as Long cnt=0, inFile=FreeFile

'' open etc.

do until eof(inFile)
  cnt += 1
  line input '' read line from file ... into the array
  redim preserve fileread(cnt+1)
loop
Last edited by MrSwiss on Apr 26, 2015 16:06, edited 1 time in total.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: "redim preserve" crashes PROG. (FB 1.03.0-64)

Post by fxm »

At the first line, the array is declared as static (fixed-sized).
So in the scope [Do...Loop], Redim defines a new local dynamic array, and the shared array is not resized.

Solution:
Define first a dynamic array:
ReDim shared as String fileread(1 to 1)
or
Dim shared as String fileread()
ReDim fileread(1 to 1)


Remark: If you compile your initial code with option -exx, a runtime error must appear in the loop.
Because at each loop iteration:
- Before instruction 'Redim', the program accesses the shared array (unresized)
- After instruction 'Redim', the program accesses the local array (increasingly resized at each loop)

Example with Dim shared as String fileread(1 to 1):

Code: Select all

Dim shared as String fileread(1 to 1)
Dim as Long cnt=0

print "    ubound(fileread)"
print "before redim", "after redim"
do until cnt=10
  cnt += 1
  print ubound(fileread),
  redim preserve fileread(cnt+1)
  print ubound(fileread)
loop

sleep

Code: Select all

    ubound(fileread)
before redim  after redim
 1             2
 1             3
 1             4
 1             5
 1             6
 1             7
 1             8
 1             9
 1             10
 1             11
Example with Redim shared as String fileread(1 to 1):

Code: Select all

Redim shared as String fileread(1 to 1)
Dim as Long cnt=0

print "    ubound(fileread)"
print "before redim", "after redim"
do until cnt=10
  cnt += 1
  print ubound(fileread),
  redim preserve fileread(cnt+1)
  print ubound(fileread)
loop

sleep

Code: Select all

    ubound(fileread)
before redim  after redim
 1             2
 2             3
 3             4
 4             5
 5             6
 6             7
 7             8
 8             9
 9             10
 10            11
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: "redim preserve" crashes PROG. (FB 1.03.0-64) [solved]

Post by MrSwiss »

Thank you fxm, this solves the issue nicely ;-) ... BTW nice examples!

I didn't know that ReDim could be used "out of the Box" to declare "dynamic"-array. (solution 1)
My impresson was: Dim first, ReDim second until ReDim n.

@admin,
may be better positioned elsewhere ... e.g. "Tips & Tricks"
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: "redim preserve" crashes PROG. (FB 1.03.0-64) [solved]

Post by fxm »

MrSwiss wrote:I didn't know that ReDim could be used "out of the Box" to declare "dynamic"-array. (solution 1)
My impression was: Dim first, ReDim second until ReDim n.
dkl,

Precisely about this syntax of 'Resize', for declare (and first sizing) a dynamic array, I would highlight a weird feature of this syntax which allows to use also the initializer '= Any':
Redim [Shared] As datatype symbolName([subscript [, ...]]) = Any
  • with this syntax, the constructor is nevertheless called!
Example:

Code: Select all

Type UDT
  Dim As Integer I = 1234
  Declare Constructor ()
End Type
Constructor UDT () : Print "ctor" : End Constructor

Dim As UDT I1 = Any : Print @I1, I1.I
Static As UDT I2 = Any : Print @I2, I2.I
Dim Shared As UDT I3 = Any : Print @I3, I3.I
Static Shared As UDT I4 = Any : Print @I4, I4.I
Print

Dim As UDT A1(0) = Any : Print @A1(0), A1(0).I
Static As UDT A2(0) = Any : Print @A2(0), A2(0).I
Dim Shared As UDT A3(0) = Any : Print @A3(0), A3(0).I
Static Shared As UDT A4(0) = Any : Print @A4(0), A4(0).I
Print

Redim As UDT B1(0) = Any : Print @B1(0), B1(0).I
Redim Shared As UDT B3(0) = Any : Print @B3(0), B3(0).I
Print

Sleep

Code: Select all

1244912        3362040
4239392        0
4239400        0
4239404        0

1244908        2009056302
4239396        0
4239408        0
4239412        0

ctor
3351808        1234
ctor
3351824        1234
Remark:
When declaring without sizing a dynamic array:
[Re]Dim [Shared] As datatype symbolName() = Any
  • '= Any' is also authorized although it is irrelevant.
Post Reply