2012-10-31 85 views
0

我在寫一個ODBC數據庫類,它包含用於從給定查詢中獲取一系列屬性和元組的元素函數。C++ ODBC未處理的異常/訪問衝突寫入位置

我的代碼中的語句一行下面這將導致此運行時錯誤是扔在調試模式:

Unhandled exception at <mem loc> in <prog name>: 0xC0000005: Access violation writing location <mem loc>. 

這裏是代碼,其中ERROR點出了問題的行:

SQLINTEGER length = 0; 
vector<vector<string>> data; 
this->sReturn = SQLFetch(this->sHandle); 

while (this->sReturn == SQL_SUCCESS) { 
    vector<string> tuple; 

for (int i = 0; i < columnCount; i++) { 
    SQLPOINTER value = ""; 

    switch (info[i].columnType) { 
    case 0 : //SQL_UNKNOWN_TYPE 
     throw DatabaseAttributeTypeUnknown("The database returned an attribute of an unknown type."); 
     break; 

    case 1 : //SQL_CHAR 
     this->sReturn = SQLGetData(this->sHandle, i + 1, info[i].columnType, value, 
     info[i].columnSize*sizeof(SQLCHAR), 
ERROR &length); 
     break; 

    //Some more cases 
    } 
} 

任何想法爲什麼這個錯誤被拋出?這是MSDN documentation on SQLGetData(),它將值分配給length

謝謝你的時間。

回答

1

當編譯器將可執行代碼映射到源中的代碼行時,它們通常不能區分被拆分爲多行的語句中的行。所以,如果調試器說,在特定的行發生錯誤,它實際上可以在任何地方,在整個聲明中,所以在某處:

this->sReturn = SQLGetData(this->sHandle, i + 1, info[i].columnType, value, 
    info[i].columnSize*sizeof(SQLCHAR), 
    &length); 

這裏唯一的搖搖欲墜的指針是value它指向一個空靜態字符串,所以包含一個空字節的一個字符長的數組。另外,根據編譯器選項,此數組可以位於只讀數據段中。雖然SQLGetData()認爲它指向的位置至少爲info[i].columnSize*sizeof(SQLCHAR)字節,並且它將從SQL列寫入(不讀取)數據。

我可能會錯過其他細節,但我的第一個猜測是,這是導致內存訪問衝突的原因。

+0

是的,你是對的。價值是罪魁禍首!謝謝! –

0

除了弗雷德裏克說的。你正在編譯你的代碼64位?如果是的話,你會發現SQLGetData需要一個指向SQLLEN的最後一個參數不是SQLINTEGER:

SQLRETURN SQL_API SQLGetData(SQLHSTMT StatementHandle, 
           SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, 
           SQLPOINTER TargetValue, SQLLEN BufferLength, 
           SQLLEN *StrLen_or_Ind); 

的SQLLEN是在64位的Windows不是4個字節爲SQLINTEGER爲8個字節。

相關問題