Speicherzugriffsfehler - Warum?



  • Hallo,

    ich habe ein Programmm geschrieben, das alle Dateien und Ordner in eine sqlite3 Datenbank speichern soll.

    Hier ist das Programm:

    // main.cpp -- Suche für Elements
    
    #include<iostream>
    #include<sqlite3.h>
    #include<cstring>
    #include<dirent.h>
    
    using namespace std;
    
    void saveFilename(char folder[], char filename[])
    {
    	cout << "Speichere Datei " << filename << " in Ordner "
    	     << folder << " in Datenbank..." << endl;
    	sqlite3 *db;
    	int rc;
    	const int charsize = strlen("INSERT INTO filenames (foldername, filename) VALUES ('") + strlen(folder) + strlen("', '") + strlen(filename) + strlen("');") + 1;
    	char sql[charsize];
    	strcat(sql, "INSERT INTO filenames (foldername, filename) " \
    	      "VALUES ('");
    	strcat(sql, folder);
    	strcat(sql, "', '");
    	strcat(sql, filename);
    	strcat(sql, "');");
    	sqlite3_open("Elements.db", &db);
    	sqlite3_exec(db, sql, 0, 0, 0);
    	sqlite3_close(db);
    }
    
    void saveFolder(char folder[], char foldername[])
    {
    	cout << "Speichere Ordner " << foldername << " in Ordner "
    	     << foldername << " in Datenbank..." << endl;
    	sqlite3 *db;
    	int rc;
    	const int charsize = strlen("INSERT OR IGNORE INTO folders (foldername, foldername2) VALUES ('") + strlen(folder) + strlen("', '") + strlen(folder) + strlen("');") + 1;
    	char sql[charsize];
    	strcat(sql, "INSERT INTO folders (foldername, foldername2) " \
    	      "VALUES ('");
    	strcat(sql, folder);
    	strcat(sql, "', '");
    	strcat(sql, foldername);
    	strcat(sql, "');");
    	sqlite3_open("Elements.db", &db);
    	sqlite3_exec(db, sql, 0, 0, 0);
    	sqlite3_close(db);
    }
    
    void indexing(char folder[])
    {
    	cout << "Öffne Ordner " << folder << "..." << endl;
    	DIR *dir;
    	struct dirent *ent;
    	unsigned char isFile = 0x8;
    	unsigned char isFolder = 0x4;
    
    	if((dir = opendir(folder)) != NULL)
    	{
    		while((ent = readdir(dir)) != NULL)
    		{
    			if(!(strcmp(".", ent->d_name) == 0) && !(strcmp("..", ent->d_name) == 0))
    			{
    				if(ent->d_type == isFile)
    				{
    					saveFilename(folder, ent->d_name);
    				}
    				else if(ent->d_type == isFolder)
    				{
    					cout << strlen(folder) << " " << strlen(ent->d_name) << " " << endl;
    					const int len = strlen(folder) + strlen(ent->d_name) + 2;
    					char newfolder[len];
    					strcpy(newfolder, folder);
    					strcat(newfolder, ent->d_name);
    					strcat(newfolder, "/");
    					cout << newfolder << endl;
    					saveFolder(folder, ent->d_name);
    					indexing(newfolder);
    				}
    			}
    		}
    		cout << "Schliesse Ordner " << folder << "..." << endl;
    		closedir(dir);
    	}
    	else
    	{
    		cout << "Fehler beim öffnen von " << folder << endl;
    	}
    
    }
    
    int main()
    {
    	int rc, rc2;
    
    	cout << "Datenbanktabellen erstellen..." << endl;
    	sqlite3 *db;
    	sqlite3_open("Elements.db", &db);
    	sqlite3_stmt *statement;
    	rc = sqlite3_exec(db, "CREATE TABLE folders (foldername TEXT, foldername2 TEXT);", 0, 0, 0);
    	rc2 = sqlite3_exec(db, "CREATE TABLE filenames (foldername TEXT, filename TEXT)", 0, 0, 0);
    	if(rc == SQLITE_OK && rc2 == SQLITE_OK) cout << " Tabellen erstellt." << endl;
    	sqlite3_close(db);
    
    	indexing("/media/Elements/");
    
    	return 0;
    }
    

    Bei einer Datei kommt aber ein Speicherzugriffsfehler. Liegt es daran, dass der Dateiname so lang ist?

    Speichere Datei In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol - Deutsche Verlags-Anstalt _Munchen_.mobi in Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60)/ in Datenbank...
    Speicherzugriffsfehler (Speicherabzug geschrieben)
    ubik@Lenovo-G770:~/Dokumente/Programmierung/Eigene Projekte/Suche für Elements$
    

    Wie könnte ich das Problem lösen?



  • Wahrscheinlich. Schau dir den Callstack beim Crash mit einem Debugger an. Steht dran, "Speicherabzug geschrieben". Muss nicht unbedingt stimmen, aber wenn tatsächlich ein dump geschrieben wurde, kannst du den mit einem Debugger anschauen. Sonst einfach dein Programm in einem Debugger starten.

    Ich würd mir die Mühe aber ehrlich gesagt nicht machen. Was du machst ist kein C++, das ist C mit cout. Ich will das erst gar nicht durchschauen. Diese ganze manuelle Stringverwaltung ist sehr fehleranfällig und in C++ überhaupt nicht nötig. Wenn du richtiges C++ schreibst, wirst du solche Probleme überhaupt nicht mehr haben.



  • In Zeilen 18 und 37 ist sql wohl nicht nullterminiert.
    Wie sehen die geschriebenen Daten aus? Oder ist "In den eisigen Tod" gleich das erste Buch?
    Ansonsten gilt, was Mechanics sagt.



  • Mechanics schrieb:

    Ich würd mir die Mühe aber ehrlich gesagt nicht machen. Was du machst ist kein C++, das ist C mit cout. Ich will das erst gar nicht durchschauen. Diese ganze manuelle Stringverwaltung ist sehr fehleranfällig und in C++ überhaupt nicht nötig. Wenn du richtiges C++ schreibst, wirst du solche Probleme überhaupt nicht mehr haben.

    Leider kann ich für die Funktionen sqlite3_exec(...) keinen C++ String verwenden, ich brauche ein const char, um die Variable sql zu übergeben.

    Die Daten sehen so aus:

    filename = "In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol - Deutsche Verlags-Anstalt _Munchen_.mobi"
    folder = "/media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60)/"
    


  • ubik schrieb:

    Leider kann ich für die Funktionen sqlite3_exec(...) keinen C++ String verwenden, ich brauche ein const char, um die Variable sql zu übergeben.

    Geht alles. string::c_str()



  • ubik schrieb:

    Leider kann ich für die Funktionen sqlite3_exec(...) keinen C++ String verwenden, ich brauche ein const char, um die Variable sql zu übergeben.

    http://en.cppreference.com/w/cpp/string/basic_string/c_str

    ubik schrieb:

    Die Daten sehen so aus:[..]

    Ich meinte die Daten, die bereits in der DB gelandet sind.



  • Die letzte Datei in der Datenbank ist:

    /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/DER SPIEGEL/DER SPIEGEL 24_12 (42)/|cover.jpg
    
    Speichere Datei cover.jpg in Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/DER SPIEGEL/DER SPIEGEL 24_12 (42)/ in Datenbank...
    Speichere Datei DER SPIEGEL 24_12 - DER SPIEGEL.pdf in Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/DER SPIEGEL/DER SPIEGEL 24_12 (42)/ in Datenbank...
    Speichere Datei metadata.opf in Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/DER SPIEGEL/DER SPIEGEL 24_12 (42)/ in Datenbank...
    Schliesse Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/DER SPIEGEL/DER SPIEGEL 24_12 (42)/...
    Schliesse Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/DER SPIEGEL/...
    54 34
    /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/
    Speichere Ordner Deutsche Verlags-Anstalt _Munchen_ in Ordner Deutsche Verlags-Anstalt _Munchen_ in Datenbank...
    Öffne Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/...
    89 64
    /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60)/
    Speichere Ordner In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60) in Ordner In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60) in Datenbank...
    Öffne Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60)/...
    Speichere Datei cover.jpg in Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60)/ in Datenbank...
    Speichere Datei In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol - Deutsche Verlags-Anstalt _Munchen_.epub in Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60)/ in Datenbank...
    Speichere Datei In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol - Deutsche Verlags-Anstalt _Munchen_.mobi in Ordner /media/Elements/Backup/2. Juli 2013/Dokumente/Calibre/Deutsche Verlags-Anstalt _Munchen_/In den eisigen Tod - Robert F. Scotts Expedition zum Sudpol (60)/ in Datenbank...
    


  • Ich wollte wissen, ob die Daten, die vor dem Absturz geschrieben wurden alle korrekt in der DB gelandet sind, nicht, was dein Programm ausgibt.

    Aber ehrlich, schreib's mit std::string und jut is.



  • Ok, hab es in String umgeändert. Das Programm läuft jetzt durch. Danke!


Anmelden zum Antworten