Delen via


Buffers toewijzen en vrijmaken

Alle buffers worden toegewezen en vrijgemaakt door de toepassing. Als een buffer niet wordt uitgesteld, hoeft deze alleen te bestaan voor de duur van de aanroep naar een functie. SQLGetInfo retourneert bijvoorbeeld de waarde die is gekoppeld aan een bepaalde optie in de buffer die wordt verwezen door het argument InfoValuePtr. Deze buffer kan direct na de aanroep naar SQLGetInfo worden vrijgemaakt, zoals wordt weergegeven in het volgende codevoorbeeld:

SQLSMALLINT   InfoValueLen;  
SQLCHAR *     InfoValuePtr = malloc(50);   // Allocate InfoValuePtr.  
  
SQLGetInfo(hdbc, SQL_DBMS_NAME, (SQLPOINTER)InfoValuePtr, 50,  
            &InfoValueLen);  
  
free(InfoValuePtr);                        // OK to free InfoValuePtr.  

Omdat uitgestelde buffers worden opgegeven in één functie en in een andere functie worden gebruikt, is het een programmeerfout in de toepassing om een uitgestelde buffer vrij te maken terwijl het stuurprogramma verwacht dat deze nog bestaat. Het adres van de *ValuePtr-buffer wordt bijvoorbeeld doorgegeven aan SQLBindCol voor later gebruik door SQLFetch. Deze buffer kan pas worden vrijgemaakt als de kolom niet afhankelijk is, zoals met een aanroep naar SQLBindCol of SQLFreeStmt , zoals wordt weergegeven in het volgende codevoorbeeld:

SQLRETURN    rc;  
SQLINTEGER   ValueLenOrInd;  
SQLHSTMT     hstmt;  
  
// Allocate ValuePtr  
SQLCHAR * ValuePtr = malloc(50);  
  
// Bind ValuePtr to column 1. It is an error to free ValuePtr here.  
SQLBindCol(hstmt, 1, SQL_C_CHAR, ValuePtr, 50, &ValueLenOrInd);  
  
// Fetch each row of data and place the value for column 1 in *ValuePtr.  
// Code to check if rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO   
// not shown.  
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {  
   // It is an error to free ValuePtr here.  
}  
  
// Unbind ValuePtr from column 1.  It is now OK to free ValuePtr.  
SQLFreeStmt(hstmt, SQL_UNBIND);  
free(ValuePtr);  

Een dergelijke fout wordt eenvoudig gemaakt door de buffer lokaal in een functie te declareren; de buffer wordt vrijgemaakt wanneer de toepassing de functie verlaat. De volgende code veroorzaakt bijvoorbeeld niet-gedefinieerd en waarschijnlijk onherstelbaar gedrag in het stuurprogramma:

SQLRETURN   rc;  
SQLHSTMT    hstmt;  
  
BindAColumn(hstmt);  
  
// Fetch each row of data and try to place the value for column 1 in  
// *ValuePtr. Because ValuePtr has been freed, the behavior is undefined  
// and probably fatal. Code to check if rc equals SQL_ERROR or   
// SQL_SUCCESS_WITH_INFO not shown.  
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {}  
  
   .  
   .  
   .  
  
void BindAColumn(SQLHSTMT hstmt)  // WARNING! This function won't work!  
{  
   // Declare ValuePtr locally.  
   SQLCHAR      ValuePtr[50];  
   SQLINTEGER   ValueLenOrInd;  
  
   // Bind rgbValue to column.  
   SQLBindCol(hstmt, 1, SQL_C_CHAR, ValuePtr, sizeof(ValuePtr),  
               &ValueLenOrInd);  
  
   // ValuePtr is freed when BindAColumn exits.  
}