ubuntuusers.de

Speicherzugriffsfehler / Segmentation fault

Status: Ungelöst | Ubuntu-Version: Ubuntu 11.04 (Natty Narwhal)
Antworten |

llf

Anmeldungsdatum:
10. August 2010

Beiträge: Zähle...

Hallo, nach dem ich heute endlich C++ mit MySQL zum Laufen brachte, kam mir eine Idee. Da ich ein Spiel programmiere (in SDL), will ich dies zu einem Onlinegame umbauen. Dafür will ich die MySQL-Datenbank als Login-Server verwenden. Was bedeutet, der Nutzer gibt Seine Email-Adresse und sein Passwort ein und das Skript überprüft dann den Rest. Als erstes wollte ich mit der MySQL-Funktion beginnen. Damit aber alles Ordentlich bleibt will ich SDL und MySQL klar von einander trennen. Jetzt habe ich eine Anwendung geschrieben, zum Testen ob das mit einer zweiten .cpp Datei und einer Header überhaupt geht. Compilen lässt es sich auch aber ausführen nicht. Wenn ich versuche es auszuführen, dann kommt folgende Fehler Meldung: Speicherzugriffsfehler. Ich hab' mir ein Build-Skript geschrieben (Shell). Wenn ich das ausführe kommt Segmentation fault. Was kann ich machen?

Hier der Quelltext von allen Dateien:

mysql.cpp:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <mysql/mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include "mysql.h"

THE_MYSQL::THE_MYSQL()
{
    conn = mysql_init(NULL);
}

THE_MYSQL::~THE_MYSQL()
{
}

void THE_MYSQL::connect()
{
    if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }
}

void THE_MYSQL::disconnect()
{
    mysql_free_result(res);
    mysql_close(conn);
}

MYSQL_RES *THE_MYSQL::send_query(char *query)
{
    if(mysql_query(conn, query)) {
        fprintf(stderr, "%s\n", mysql_error(conn));
        exit(1);
    }

    return mysql_use_result(conn);
}

mysql.h:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef MYSQL_H
#define MYSQL_H

#include <mysql/mysql.h>

class THE_MYSQL
{
public:
    char *server;
    char *user;
    char *password;
    char *database;

    THE_MYSQL();
    ~THE_MYSQL();
    void connect();
    void disconnect();
    MYSQL_RES *send_query(char *query);

private:
    MYSQL     *conn;
    MYSQL_RES *res;
};

#endif

main.cpp:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <mysql/mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include "mysql.h"

int main() {
    MYSQL_RES *resource;
    MYSQL_ROW  row;

    THE_MYSQL *connection;
    connection->server   = "localhost";
    connection->user     = "root";
    connection->password = "imkampe";
    connection->database = "game";
    connection->connect();

    resource = connection->send_query("show tables");

    connection->disconnect();
}

compile.sh:

1
2
3
4
g++ -c main.cpp -o main.o
g++ -c mysql.cpp -o mysql.o
g++ -o output-file $(mysql_config --cflags) main.cpp mysql.cpp $(mysql_config --libs)
./output-file

Danke für alle Antworten.

PS: Bitte sagt jetzt nicht das es doch viel praktischer ist ein Makefile zu benutzen. Ich finde Makefiles zu umständlich und hab' oft schlechte Erfahrungen gesammelt mit ihnen.

EManu

Avatar von EManu

Anmeldungsdatum:
5. August 2010

Beiträge: 47

Erstmal musst du herausfinden, wo genau der segfault passiert. Im einfachsten Fall kriegst du das mit einem Debugger raus, indem du den code einfach durchsteppst (Zeile für Zeile ausführen lassen und gucken, wann's knallt). Wenn es ein komplizierteres Projekt ist, kannst dir auch mal Val-/Cachegrind anschauen. Wenn du in der Konsole bleiben möchtest (also keine IDE), mach dich mal über die Benutzung von gdb schlau.

Bezüglich Makefiles stimme ich dir absolut zu. Leider wird es mit wachsender Größe des Projekts noch umständlicher, sich manuell um die Abhängigkeiten zu kümmern 😉

JuergenF

Anmeldungsdatum:
22. Oktober 2004

Beiträge: 2009

Wohnort: FFM

Ich habe jetzt gerade keine Lust, das nachzubauen - und Du sollst ja auch lernen 😉

ob das mit einer zweiten .cpp Datei und einer Header überhaupt geht.

Heisst das, Du hast bisher nur eine Klasse? Dann scheinst Du ja recht am Anfang zu sein.

Insgesamt klingt das für mich, als solltest Du Dich mit dem Gebrauch von einem Debugger, im GNU-Land wohl hauptsächlich GDB, vertraut machen.

Vermutlich wird Dir eine der in dem Artikel genannten grafischen Oberflächen eher gefallen, als das Kommandozeilen-Ding. Der nemiver sieht recht nett aus... (der ddd scheint mir etwas komplexer, aber mit dem kannst Du Dir Deine Datenstrukturen im Speicher grafisch anzeigen lassen - das ist bei dem ein tolles Feature. Auch wenn er etwas ältlich daher kommt, kannst ihn Dir ja evtl. später mal angucken).

Wenn Du Dein Programm mit Debug-Symbolen Übersetzt und es dann im Debugger ausführst, wird Dir genau die Quellcode-Zeile angezeigt, in der der Fehler auftritt - und Du kannst Dir alle Variablen anzeigen lassen und so herausfinden, welche davon gerade NULL ist und den Fehler verursacht.

PS: Bitte sagt jetzt nicht das es doch viel praktischer ist ein Makefile zu benutzen. Ich finde Makefiles zu umständlich und hab' oft schlechte Erfahrungen gesammelt mit ihnen.

Das mit den 'schlechten Erfahrungen' solltest Du evtl. mal in einem eigenen Posting diskutieren (lassen). Wenn ein Projekt mal mehr als ~20 cpp-Dateien hat, ist man doch eher erfreut, wenn das Compilen nur 10sec statt 5min dauert.

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Alleine wenn man ein char * in C++ Code sieht, sollten schon die Alarmglocken klingeln... die Haltung zu Makefiles bestätigen mir irgend wie, dass der OP mit C++ nicht gerade eine gute Wahl für sich getroffen hat. Man sollte nicht gegen eine Sprache entwickeln; wenn einem wichtige Themen in diesem Kontext zu komplex erscheinen, dann hat man evtl. die falsche Sprache gewählt.

vinho

Anmeldungsdatum:
10. September 2010

Beiträge: 91

llf schrieb:

Wenn ich versuche es auszuführen, dann kommt folgende Fehler Meldung: Speicherzugriffsfehler.

1
2
3
    THE_MYSQL *connection;
    connection->server   = "localhost";
    // ...

Du legst einen Zeiger an und dereferenzierst ihn, ohne ihn zu initialisieren? Richtig:

1
2
3
    THE_MYSQL *connection = new THE_MYSQL();
    connection->server   = "localhost";
    // ...
Antworten |