Microsoft KB Archive/65478

= 7.10 Memory Lost If Reassign $DYNAMIC String Array to STRING$ =

Article ID: 65478

Article Last Modified on 10/20/2003

-

APPLIES TO


 * Microsoft BASIC Professional Development System 7.0
 * Microsoft BASIC Professional Development System 7.1

-



This article was previously published under Q65478



SYMPTOMS
In a compiled .EXE file, assigning a $DYNAMIC variable-length-string array element directly to a Basic intrinsic string function (such as STRING$) creates an internal temporary string that may fail to be deallocated. Repetitive reassignments can cause &quot;Out of String Space&quot; or &quot;Out of Memory&quot; errors. This article documents this problem with Microsoft Basic Professional Development System (PDS) versions 7.00 and 7.10 and shows two examples of the problem.



STATUS
Microsoft has confirmed this to be a bug in Basic PDS versions 7.00 and 7.10 for MS-DOS and MS OS/2. This problem does not occur in the QBX.EXE environment, or in earlier versions of Microsoft Basic Compiler or QuickBasic. We are researching this problem and will post new information here as it becomes available.



MORE INFORMATION
The problem can occur for dynamic variable-length-string array element assignments of the form A$(x)=STRING$(n). But this form of assignment may not give the problem in some cases, such as in Code Example 1 where A$(x)=STRING$(n) appears within a FOR...NEXT loop.

Any one of the following code modifications works around the problem:

 Use a $STATIC array instead of a $DYNAMIC array, -or-

  First assign a temporary variable such as temp$ to the Basic string function (STRING$), then assign the array element to temp$: temp$=STRING$(12000) A$(1)=temp$ temp$=&quot;&quot; -or-

 Use the CLEAR statement to erase the memory wasted by the internal temporary string (but CLEAR also erases all other variables). -or-

 In some cases, surrounding the assignment with a FOR...NEXT structure may eliminate the problem, such as in Code Example 1.

This problem is not affected by any compiler options that limit optimizations (BC /D, /X, etc.). The problem occurs with both near and far strings (BC /Fs, /Fn).

Code Example 1
The following code example shows one case (in a FOR...NEXT block) that reclaims memory properly and three cases that fail to return the string memory. In the cases that fail, the a$=SPACE$ statement fails to release an amount of string space equal to the length of the string assigned (due to an internal unreleased temporary string). Repeated assignments will decrease string memory until string memory eventually runs out.

Compile and LINK as follows (compile and LINK options do not affect the problem): BC STRING; LINK STRING; REM $DYNAMIC CLS DIM a$(10) PRINT &quot;FRE(a$(1)) at start of program: &quot;, FRE(a$(1))

PRINT &quot;Case #1: memory recovered if string deallocated in FOR loop.&quot; PRINT &quot;For loop works fine -- memory restored&quot; FOR i% = 12000 TO 0 STEP -12000

a$(1) = SPACE$(i%) PRINT &quot;Free during FOR loop: &quot;, FRE(a$(1))

NEXT

PRINT &quot;Case #2: Prompt user for size of string.&quot; INPUT &quot;Input big number (try 12000):&quot;, big% a$(1) = SPACE$(big%)  'Both A$(1) & internal string consume memory: PRINT &quot;FRE(a$(1)) after allocation: &quot;, FRE(a$(1)) INPUT &quot;Input a small number (0):&quot;, small% a$(1) = SPACE$(small%) 'Internal temporary string still wastes memory: PRINT &quot;FRE(a$(1)) after deallocation: &quot;, FRE(a$(1))

PRINT PRINT &quot;Case #3. String of 12000 bytes assigned.&quot; big% = 12000 a$(1) = SPACE$(big%) PRINT &quot;FRE(a$(1)) after allocation: &quot;, FRE(a$(1)) small% = 0 a$(1) = SPACE$(small%) PRINT &quot;FRE(a$(1)) after deallocation: &quot;, FRE(a$(1))

PRINT &quot;Case #4: Another string of 12000 bytes assigned.&quot; a$(1) = SPACE$(12000) PRINT &quot;FRE(a$(1)) after allocation: &quot;, FRE(a$(1)) a$(1) = SPACE$(0) PRINT &quot;FRE(a$(1)) after deallocation: &quot;, FRE(a$(1)) END

Code Example 2
The program below shows that the problem also occurs in $DYNAMIC arrays in SUBprograms.

Compile and link as follows: BC STRING2.BAS ; LINK STRING2 ;

DECLARE SUB sub1

CALL sub1 END

SUB sub1

DIM s(2) AS STRING  'This array is dynamic, since SUB is non-STATIC PRINT &quot;FRE before string allocation: &quot;; FRE(s(0)) s(1) = STRING$(1000, 255) PRINT &quot;FRE after string allocation: &quot;; FRE(s(1)) s(1) = &quot;&quot; PRINT &quot;FRE after string deallocation: &quot;; FRE(s(2))

END SUB

Additional query words: BasicCom SR# S900816-176 buglist7.00 buglist7.10

Keywords: KB65478

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.