配置及釋放緩衝區
應用程式會配置並釋放所有緩衝區。 如果緩衝區不延遲,緩衝區只需在呼叫函式時存在。 例如,SQLGetInfo 會傳回 InfoValuePtr 引數指向的緩衝區中,特定選項關聯的值。 呼叫 SQLGetInfo 後,您可以立即釋放此緩衝區,如下列程式碼範例所示:
SQLSMALLINT InfoValueLen;
SQLCHAR * InfoValuePtr = malloc(50); // Allocate InfoValuePtr.
SQLGetInfo(hdbc, SQL_DBMS_NAME, (SQLPOINTER)InfoValuePtr, 50,
&InfoValueLen);
free(InfoValuePtr); // OK to free InfoValuePtr.
因為延遲的緩衝區是一個函式指定,並用於另一個函式,所以是應用程式程式設計錯誤:驅動程式仍預期緩衝區存在,但應用程式釋放延遲的緩衝區。 例如,*ValuePtr 緩衝區的位址會傳遞至 SQLBindCol ,以供 SQLFetch 之後使用。 在資料行解除繫結前 (例如呼叫 SQLBindCol 或 SQLFreeStmt),無法釋放此緩衝區,如下列程式碼範例所示:
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);
這類錯誤很容易在函式中本機宣告緩衝區時發生;因為應用程式離開函式後會釋放緩衝區。 例如,下列程式碼會導致驅動程式中未定義且可能嚴重的行為:
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.
}