2

我正在使用 C 在 vs2012 中实现 SQLite Prepare-Statement。

我使用此链接作为教程来捕获每次运行代码时在我的机器上运行的进程。一切正常,除了准备语句不允许我将它放在 do-while 循环之外。如果我把它放在 do-while 循环中,那么我实际上什么都不做,因为每次插入 db 时,prepare-statement 都会再次执行,这是不切实际的。但是,当我将准备语句放在 do-while 循环中并运行代码时,它可以正常工作(但它运行的插入次数与我必须插入的次数一样多)。当我放在 do-while 循环之外时,它会给我一个内存警告和中断。

这是我如何实现 SQLite:

BOOL GetProcessList(sqlite3 *db)
{
  HANDLE hProcessSnap;
  HANDLE hProcess;
  PROCESSENTRY32 pe32;
  DWORD dwPriorityClass;
  sqlite3_stmt* stmt;
  char *errorMessage;  
  char query[80] = "INSERT INTO Process_list VALUES (?1, ?2, ?3, ?4, ?5);";

  // Take a snapshot of all processes in the system.
  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {
    printError( TEXT("CreateToolhelp32Snapshot (of processes)") );
    return( FALSE );
  }

  // Set the size of the structure before using it.
  pe32.dwSize = sizeof( PROCESSENTRY32 );

  // Retrieve information about the first process,
  // and exit if unsuccessful
  if( !Process32First( hProcessSnap, &pe32 ) )
  {
    printError( TEXT("Process32First") ); // show cause of failure
    CloseHandle( hProcessSnap );          // clean the snapshot object
    return( FALSE );
  }

  // Now walk the snapshot of processes, and
  // display information about each process in turn

  sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS Process_list("  
    "Process_ID     INT PRIMARY KEY     , " 
    "Thread_count       INT     ,   "
    "Parent_PID     INT     ,   "
    "Priority_Base      INT     ,   " 
    "Priority_class INT     );", NULL, NULL, &errorMessage);

    sqlite3_prepare_v2(db, query,strlen(query), &stmt,NULL); // can't put it here

  do
  {
    _tprintf( TEXT("\n\n=====================================================" ));
    _tprintf( TEXT("\nPROCESS NAME:  %s"), pe32.szExeFile );
    _tprintf( TEXT("\n-------------------------------------------------------" ));

    // Retrieve the priority class.
    dwPriorityClass = 0;
    hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );
    if( hProcess == NULL )
    {
      printError( TEXT("OpenProcess") );
    } else {
        dwPriorityClass = GetPriorityClass( hProcess );
        if( !dwPriorityClass )
        {
            printError( TEXT("GetPriorityClass") );
        }
        CloseHandle( hProcess );
    }

    _tprintf( TEXT("\n  Process ID        = 0x%08X"), pe32.th32ProcessID );
    _tprintf( TEXT("\n  Thread count      = %d"),   pe32.cntThreads );
    _tprintf( TEXT("\n  Parent process ID = 0x%08X"), pe32.th32ParentProcessID );
    _tprintf( TEXT("\n  Priority base     = %d"), pe32.pcPriClassBase );
    if( dwPriorityClass )
      _tprintf( TEXT("\n  Priority class    = %d"), dwPriorityClass );
    _tprintf( TEXT("\n"));

    //-------------------------------------------------------------------------------
    // database insertion of the process information    
    sqlite3_bind_int64(stmt,1,pe32.th32ProcessID);
    sqlite3_bind_int64(stmt,2,pe32.cntThreads);
    sqlite3_bind_int64(stmt,3,pe32.th32ParentProcessID);
    sqlite3_bind_int64(stmt,4,pe32.pcPriClassBase);
    sqlite3_bind_int64(stmt,5,dwPriorityClass); 
    if(sqlite3_step(stmt) != SQLITE_DONE)
        printf("\nPrepare statement failed!\n");
    sqlite3_reset(stmt);                        // the error appears here
    sqlite3_finalize(stmt);
    //-------------------------------------------------------------------------------

    // List the modules and threads associated with this process
    ListProcessModules( pe32.th32ProcessID,db );
    ListProcessThreads( pe32.th32ProcessID,db );

  } while( Process32Next( hProcessSnap, &pe32 ) );

  CloseHandle( hProcessSnap );
  return( TRUE );
}

所以当我运行代码时,它会告诉我:

信息

那么为什么会发生这种情况以及如何避免这种内存异常呢?谢谢

4

1 回答 1

3
  1. 您必须检查所有函数的返回值,尤其是sqlite3_prepare_v2. (如果出现错误,请调用sqlite3_errmsg以获取有用的错误消息。)
  2. 您可以多次使用准备好的语句,并且必须sqlite3_reset在重用它之前调用它,这是正确的。但是,sqlite3_finalize完全释放语句;你必须在循环之后调用它。
于 2013-09-06T12:22:53.680 回答