Aracılığıyla paylaş


Arabellek ayırma ve serbest bırakma

Tüm arabellekler uygulama tarafından ayrılır ve serbest bırakılır. Arabellek ertelenmiyorsa, yalnızca bir işlev çağrısı süresince mevcut olması yeterlidir. Örneğin, SQLGetInfo , InfoValuePtr bağımsız değişkeninin işaret ettiği arabellekteki belirli bir seçenekle ilişkili değeri döndürür. Bu arabellek, aşağıdaki kod örneğinde gösterildiği gibi SQLGetInfo çağrısından hemen sonra serbestleştirilebilir:

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

Ertelenmiş arabellekler bir işlevde belirtildiğinden ve başka bir işlevde kullanıldığından, sürücü yine de var olmasını beklerken ertelenen bir arabelleği boşaltmak bir uygulama programlama hatasıdır. Örneğin, *ValuePtr arabelleğinin adresi SQLFetch tarafından daha sonra kullanılmak üzere SQLBindCol'a geçirilir. Aşağıdaki kod örneğinde gösterildiği gibi SQLBindCol veya SQLFreeStmt çağrısı gibi sütun bağlantısı kaldırılana kadar bu arabellek serbest bırakılamaz.

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);  

İşlevde arabellek yerel olarak bildirildiğinde böyle bir hata kolayca yapılabilir; uygulama işlevden ayrıldığında arabellek serbest bırakılır. Örneğin, aşağıdaki kod sürücüde tanımsız ve muhtemelen ölümcül davranışlara neden olur:

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.  
}