0

特定のクエリから一連の属性とタプルを取得するために使用されるメンバー関数を含む ODBC データベース クラスを作成しています。

以下のステートメントには、このランタイム エラーがデバッグ モードでスローされる原因となる 1 行のコードがあります。

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

このエラーがスローされる理由について何か考えはありますか? に値を割り当てているSQLGetData() に関する MSDN ドキュメントを次に示しますlength

お時間をいただきありがとうございます。

4

2 に答える 2

1

コンパイラが実行可能コードをソース内のコード行にマップする場合、通常、複数の行に分割されたステートメント内の行を区別できません。そのため、デバッガーが特定の行でエラーが発生したと言った場合、実際にはステートメント全体のどこにでもある可能性があるため、次の場所のどこかにある可能性があります。

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

ここでの唯一の不安定なポインターはvalue、null 静的文字列を指すため、null バイトを含む 1 文字の長さの配列を指します。また、コンパイラ オプションによっては、この配列を読み取り専用のデータ セグメントにすることもできます。SQLGetData() は、サイズが少なくともinfo[i].columnSize*sizeof(SQLCHAR)バイトであり、SQL 列からデータを書き込む (読み取らない) 場所を指していると考えています。

他の詳細を見落としている可能性がありますが、最初の推測では、それがメモリ アクセス違反の原因であるということです。

于 2012-10-31T02:38:42.033 に答える
0

フレデリックが言ったことに加えて。コードを 64 ビットでコンパイルしていますか? その場合、SQLGetData は、SQLINTEGER ではなく、最後の引数として SQLLEN へのポインターを取ることがわかります。

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

SQLLEN は、SQLINTEGER のように 4 バイトではなく、64 ビット ウィンドウでは 8 バイトです。

于 2012-10-31T08:16:01.850 に答える