다음을 통해 공유


버퍼 할당 및 해제

모든 버퍼는 애플리케이션에 의해 할당되고 해제됩니다. 버퍼가 지연되지 않으면 함수 호출 기간 동안만 존재해야 합니다. 예를 들어 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 버퍼의 주소는 SQLFetch에서 나중에 사용하기 위해 SQLBindCol전달됩니다. 다음 코드 예제와 같이 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.  
}