SQLite3: Fehler bei column 3(MyProgramm.exe funktioniert nicht mehr)



  • Hi Leute,
    Ich fange gerade, wie ihr sicherlich schon bemerkt habt, mit SQLite3 an. Nun wollte ich mir eine kleine Funktion schreiben, um zu überprüfen, ob ich alles verstanden hab und um mir das Leben vielleicht ein bisschen einfacher zu machen. Klappt auch so weit, nur stürzt er bei column = 2(Array, also eg. bei column 3) immer ab. Mein query zum erstellen der Tabellen:

    char *query;
    query = "CREATE TABLE if not exists TEXTURES("             \
            "ID INT PRIMARY KEY                NOT NULL,"      \
            "NAME           TEXT               NOT NULL,"      \
            "PATH           CHAR (260)         NOT NULL ); "   \
            "CREATE TABLE if not exists AREAS("                \
            "ID INT PRIMARY KEY                NOT NULL,"      \
            "X              FLOAT              NOT NULL,"      \
            "Y              FLOAT              NOT NULL,"      \
            "TEXTURE        UNSIGNED INTEGER   NOT NULL ); "   \
            "CREATE TABLE if not exists DATA("                 \
            "ID INT PRIMARY KEY                NOT NULL,"      \
            "PWTODO         FLOAT                      ,"      \
            "PWDONE         FLOAT                      ,"      \
            "YWTODO         FLOAT                      ,"      \
            "YWDONE         FLOAT                      );"     ;
    

    Mein query zum einfügen einer Zeile:

    query = "INSERT into TEXTURES VALUES(0, 'TEST Beschreibung', 'Pfad');";
    

    und hier mein Funktionsaufruf:

    query = "SELECT * from TEXTURES;";
    
    int numOfResults = 0;
    char ***results;
    char ***columnNames;
    
    if(!Project->execute(query, &numOfResults, &results, &columnNames))
      {
      wprintf(L"Reading TEXTURES table failed\n");
      system("pause");
      }
    else
      {
      wprintf(L"Reading TEXTURES table successful\n");
      }
    
    wprintf(L"Results: %i\n", numOfResults);
    for(int i = 0; i < numOfResults; i++)
       {
       wprintf(L"%S = %S\n", *columnNames[i], *results[i]);
       }
    wprintf(L"\n");
    system("pause");
    

    Hier noch die oben angesprochene (Member-)Funktion:

    bool execute(char *query, int *numOfResults, char ****results, char ****columnNames)
        {
        *numOfResults = 0;
    
        sqlite3_stmt *stmt;
        sqlite3_stmt *stmtCount;
        int rv;
    
        rv = sqlite3_prepare_v2(db, query, -1, &stmt, 0);
        if(rv)
          {
          return false;
          }
        wprintf(L"Prepared \"stmt\"\n");
    
        rv = sqlite3_prepare_v2(db, query, -1, &stmtCount, 0);
        if(rv)
          {
          return false;
          }
        wprintf(L"Prepared \"stmtCount\"\n");
    
        int columns = sqlite3_column_count(stmtCount);
        int row = 0;
    
        rv = sqlite3_step(stmtCount);
        while(rv == SQLITE_ROW)
          {
          rv = sqlite3_step(stmtCount);
          row++;
          }
        wprintf(L"Rows: %i\n  Columns: %i\n  Total: %i\n", row, columns, row * columns);
    
        try
          {
          *columnNames = (char***)malloc(row * sizeof(char**));
          *results     = (char***)malloc(row * sizeof(char**));
          }
        catch(std::bad_alloc)
          {
          wprintf(L"Bad Alloc\n");
          }
    
        row = 0;
        rv = sqlite3_step(stmt);
        while(rv == SQLITE_ROW)
          {
          wprintf(L"Current row: %i\n", row);
          try
            {
            *columnNames[row] = (char**)malloc(columns * sizeof(char*));
            *results[row]     = (char**)malloc(columns * sizeof(char*));
            }
          catch(std::bad_alloc)
            {
            wprintf(L"Bad Alloc\n");
            }
    
          for(int column = 0; column < columns; column++)
            {
            wprintf(L"  Column: %i ", column);
            *columnNames[row][column] = (char*)sqlite3_column_name(stmt, column);
            *results[row][column]     = (char*)sqlite3_column_text(stmt, column);
            wprintf(L"read\n");
            }
    
          wprintf(L"Entering next row(%i)\n", row + 1);
          rv = sqlite3_step(stmt);
          row++;
          }
        wprintf(L"\n");
    
        *numOfResults = row * columns;
    
        return true;
        }
    

    Ich habe es schon mal versucht, anstatt eines "CHAR (260)" einen "TEXT" zu nutzen, was aber nichts gebracht hat. Wenn ich mir die DB mit einem SQLite3 DB browser ansehe, wird die erstellte Zeile angezeigt, d.H., dass sie richtig erstellt wird.
    Hier noch mal kurz die Ausgaben des Programmes:

    Prepared "stmt"
    Prepared "stmtCount"
    Rows: 1
      Columns: 3
      Total: 3
    Current row: 0
      Column: 0 read
      Column: 1 read
      Column: 2
    

    ---MyProgramm.exe funktioniert nicht mehr---
    Danke, dass ihr (fast) immer versucht mir zu helfen 😃 🙂
    MfG
    DragonRaider



  • Hi,
    Ich glaube, ich weiß jetzt, woran's liegt... Ich habe total dumme Fehler in meinen mallocs... Wird jetzt gefixt und dann der neue Code hoch geladen 😉



  • Dachte ich... 😉
    Die (Member-)Funktion sieht jetzt wie folgt aus:

    bool execute(char *query, int *columns, int *rows, char ****results, char ****columnNames)
        {
        sqlite3_stmt *stmt;
        int rv;
    
        rv = sqlite3_prepare_v2(db, query, -1, &stmt, 0);
        if(rv)
          {
          return false;
          }
        wprintf(L"Prepared \"stmt\"\n");
    
        int columnsTmp = sqlite3_column_count(stmt);
        int row = 0;
    
        try
          {
          *columnNames = (char***)malloc(0);
          *results     = (char***)malloc(0);
          }
        catch(std::bad_alloc)
          {
          wprintf(L"Bad Alloc\n");
          }
    
        row = 0;
        rv = sqlite3_step(stmt);
        while(rv == SQLITE_ROW)
          {
          wprintf(L"Current row: %i\n", row);
          try
            {
            realloc(*columnNames, (row + 1) * sizeof(char**));
            realloc(*results, (row + 1) * sizeof(char**));
    
            realloc(*columnNames[row], columnsTmp * sizeof(char*));
            realloc(*results[row], columnsTmp * sizeof(char*));
            }
          catch(std::bad_alloc)
            {
            wprintf(L"Bad Alloc\n");
            }
    
          for(int column = 0; column < columnsTmp; column++)
            {
            wprintf(L"  Column: %i ", column);
            *columnNames[row][column] = (char*)sqlite3_column_name(stmt, column);
            *results[row][column]     = (char*)sqlite3_column_text(stmt, column);
            wprintf(L"read\n");
            wprintf(L"    %S = %S\n", (char*)sqlite3_column_name(stmt, column), (char*)sqlite3_column_text(stmt, column));
            }
          wprintf(L"Finished reading row %i\n", row - 1);
    
          rv = sqlite3_step(stmt);
          row++;
          }
        wprintf(L"\n");
    
        *rows = row;
        *columns = columnsTmp;
    
        return true;
        }
    

    Und der Aufruf so:

    query = "SELECT * from TEXTURES;";
    
    int rows = 0;
    int columns = 0;
    char ***results;
    char ***columnNames;
    
    if(!Project->execute(query, &rows, &columns, &results, &columnNames))
      {
      wprintf(L"Reading TEXTURES table failed\n");
      system("pause");
      }
    else
      {
      wprintf(L"Reading TEXTURES table successful\n");
      }
    
    wprintf(L"Results: %i\n", rows);
    for(int i = 0; i < rows; i++)
      {
      wprintf(L"%i. result row:\n", i);
      for(int j = 0; j < columns; ++j)
        {
        wprintf(L"  %S = %S\n", columnNames[i][j], results[i][j]);
        }
      }
    wprintf(L"\n");
    free(columnNames);
    free(results);
    system("pause");
    

    Die erzielten Ausgaben sind:

    Prepared "stmt"
    Current row: 0
      Column: 0 read
        ð÷~♥³±~♥ = 0
      Column: 1 read
        NAME = TEST Beschreibung
      Column: 2
    

    Ohne die Zeilen 48-49 gibt er folgendes aus(Die Ausgaben aus Zeile 18-27 raus geschnitten:

    Prepared "stmt"
    Current row: 0
      Column: 0 read
        ID = 0
      Column: 1 read
        NAME = TEST Beschreibung
      Column: 2 read
        PATH = Pfad
    Finished reading row: 0
    

    Könnt Ihr mir bitte helfen? Ich denke, es liegt an den reallocs, ein testweises multiplizieren der Bytes mit drei brachte jedoch auch keine Besserung...
    MfG
    DragonRaider



  • Willst/kannst du nicht einen C++ Wrapper benutzen? Der nimmt dir die ganze Speicherfriemelei ab und du kannst dich auf´s Wesentliche konzentrieren.



  • Hi DocShoe,
    Ich würde gerne den Fehler in meinem Programm kennen(aus Fehlern lernen kann sehr nützlich sein), aber für's erste eigentlich schon... Kennst du zufälligerweise einen, der auch kommerziell kostenlos nutzbar ist?
    Danke schon mal.
    MfG
    DragonRaider



  • char ****
    

    Nein


Log in to reply