Microsoft KB Archive/105807

= PRB: GP Fault if Uninitialized String Passed to API Function =

Article ID: 105807

Article Last Modified on 12/9/2003

-

APPLIES TO


 * Microsoft Visual Basic 2.0 Standard Edition
 * Microsoft Visual Basic 3.0 Professional Edition
 * Microsoft Visual Basic 2.0 Professional Edition
 * Microsoft Visual Basic 3.0 Professional Edition

-



This article was previously published under Q105807



SYMPTOMS
When you incorrectly call a Windows API function as described in the CAUSE section further below, you can receive a general protection (GP) fault

Application error: VB caused a General Protection Fault in VB.EXE at nnnn:nnnn

or one of the following error messages:

Assertion failed

-or-

Bad handle

-or-

Bad heap block



CAUSE
Invoking a Windows API function in any of the following incorrect ways can give you a GP fault or another memory violation error:


 * A passed string initialized to a value that is too short to receive the return value (See example below.)
 * Incorrect placement of ByVal in the Declare statement
 * Undefined parameters in the function declaration or invocation
 * Incorrect type or length of parameters in the function declaration or invocation

Windows requires you to ensure memory integrity when calling API functions.



WORKAROUND
If you get a GP fault or another memory error when calling a Windows API function, check that you have properly defined and passed all parameters.



STATUS
This behavior is by design.



MORE INFORMATION
String parameters passed from Visual Basic to Windows API functions must be initialized to at least the size of the data returned in them, or else you may get a general protection fault.

The following example causes a GP fault by invoking the GetProfileString API function with a string initialized with a too-small value.

Steps to Reproduce Behavior
 Start Visual Basic with a new, empty project.  Place the following correct Declare statement for GetProfileString in the General Declarations section: 'Enter the following Declare statement as one, single line: Declare Function GetProfileString Lib "Kernel" (ByVal lpAppName As String, ByVal lpKeyName As String,     ByVal lpDefault As String, ByVal lpReturnedString As String,      ByVal nsize As Integer) As Integer

'NOTE: The GetProfileString function is located in the KERNAL.DLL file, 'which is usually located in the \WINDOWS\SYSTEM directory   Add a Command button to Form1, and add the following code to the Command1_Click event procedure: dim size, str1 as string str1 = ""   ' To avoid GP fault, initialize with a longer string: ' str1="abcdefghijklmnopqrstuvwxyz" size = GetProfileString("intl", "sLongDate", "-1", str1, 1024) The above API function looks in the WIN.INI file under the [intl] section and retrieves the string after sLongDate=. The function returns a string in the address of its fourth argument. If you fail to define the fourth argument or you initialize it to a string that is smaller than the retrieved string, an assertion error occurs. If you define the fourth argument with a string that is larger than the retrieved string, the call will succeed. For example, change the line str1="" to str1="abcdefghijklmnopqrstuvwxyz" and the code will work.  Execute the code. VB.EXE will give the following error messages:

An error has occurred in your application. If you choose Ignore, you should save your work in a new file. If you choose Close your application will terminate.  

followed by:

Application error: VB caused a General Protection Fault in VB.EXE at 004A:0122

</li></ol>

Windows API functions must be called with valid parameters. If you in effect tell Windows to overwrite some part of Visual Basic internal memory, this usually causes a GP fault or other memory problem. This usually ends the Visual Basic session. In Windows version 3.1, memory of other Windows applications should not be affected. But in Windows version 3.0, a GP fault means you must restart Windows itself, thus ending all current applications in memory.

<div class="references_section">