sqlite3_column_text возвращенные данные будут повреждены во время финализации / закрытия - PullRequest
6 голосов
/ 10 января 2012

Я не уверен, что здесь происходит, но я обнаружил, что возвращаемые данные из sqlite3_column_text изменяются на этапе финализации / закрытия sqlite.

  // rc not handled in this abbreviated code

  sqlite3 *db;
  sqlite3_stmt *stmt;
  char * sql;

  const char * tail;
  int rc;

  char * dbName = "C:\\db\\myblobs.db";
  int myIndex = 0;

  char * myLocation1;
  string myLocation2;   

  rc = sqlite3_open(dbName, &db);

  sql = "SELECT location FROM blobs WHERE key = ?";
  rc = sqlite3_prepare(db, sql, strlen(sql), &stmt, &tail);
  sqlite3_bind_int(stmt, 1, myIndex);
  rc = sqlite3_step(stmt);

  myLocation1 = (char*)sqlite3_column_text(stmt, 0);
  myLocation2 = (char*)sqlite3_column_text(stmt, 0);

  // can process myLocation1 & myLocation2 fine here

  sqlite3_finalize(stmt); // data myLocation1 points to get corrupted
  sqlite3_close(db);      // data myLocation2 points to gets further corrupted

Проблема связана с myLocation1. Данные, на которые он указывает, хороши, пока не попадут в операторы sqlite3_finalize и sqlite3_close. Однако mylocation2 остается неизменным. Так что не уверен, что здесь происходит. После выполнения sqlite3_close (db) myLocation1 идентифицируется как «Bad Ptr» в Visual Studio 2010.

Любая помощь наиболее ценится.

1 Ответ

8 голосов
/ 10 января 2012

Из тонкой инструкции :

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
[...]
Возвращенные указатели действительны до тех пор, пока не произойдет преобразование типа, как описано выше, или пока не будет вызван sqlite3_step() или sqlite3_reset() или sqlite3_finalize().

Поэтому, как только вы вызовете sqlite3_finalize, возвращаемые значения из sqlite3_column_text станут недействительными, а ваши указатели myLocation1 и myLocation2 будут указывать на мусор.

Если вам нужны эти строки после вызова sqlite3_finalize, вам придется скопировать их в память, которой вы управляете. Фактически, поскольку действительны до тех пор, пока не произойдет преобразование типа note, вам следует скопировать их немедленно и использовать (char*)sqlite3_column_text(stmt, 0);, пока вы создаете свои собственные копии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...