Hallo allerseits,
warum liefert der folgende code einen "segmentation fault error", er
wird unter linux Suse 10.1 compiliert und ausgeführt.
#include <mysql/mysql.h>
#include <stdio.h>
#include <string.h>
int main()
{
MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row;
char query[80];
mysql_init(&mysql);
mysql_real_connect(&mysql,"localhost","yyy","xxx","test",0,NULL,0);
sprintf(query,"SELECT * FROM test");
mysql_real_query(&mysql,query,(unsigned int)strlen(query));
res = mysql_use_result(&mysql);
while(row = mysql_fetch_row(res))
printf("%s %sn",row[0],row[1]);
mysql_free_result(res);
return 0;
}
Was muss geändert werden ?
Danke im Voraus !
Hi
oder erstmal anfangen auch nur ein Mindestmaß an Fehlerbehandlung
einzubauen. Wer sagt denn das mysql_init(&mysql) ff. überhaupt
erfolgreich sind.
Matthias
Also
MYSQL mysql;
mysql_init(&mysql);
sieht schon mal ganz böse aus, weil mysql_init doch den Speicher
allozieren will. Demnach würde ich mal das hier versuchen:
MYSQL *mysql = (MYSQL*) 0;
mysql_init(mysql);
Unabhängig vom konkreten Problem zum Stil: Stichwort "Defensive
Programmierung". Geh davon aus, dass Funktionen, die Fehler
zurückliefern können, es auch ab und zu tun werden.
Danke erstmal, seitens der DB müsste es klappen, der obige code ist
nicht der einzige den ich probiert habe.
MYSQL *mysql = (MYSQL*) 0; ändert leider nichts.
etwas länger und "sicherer" und ebenfalls segfault:
#include <mysql/mysql.h>
#include <stdio.h>
#include <string.h>
int main(){
MYSQL *mysql;
MYSQL_RES *res;
MYSQL_ROW row;
char *query;
int t,r;
mysql_init(mysql);
if (!mysql_real_connect(mysql,"localhost","apc0",
"xxx","test",0,NULL,0))
{
printf( "Error connectin ot database: %s\n",mysql_error(mysql));
}
else printf("Connected...\n");
query="select * from test";
t=mysql_real_query(mysql,query,(unsigned int) strlen(query));
if (t)
{
printf("Error making query: %s\n",
mysql_error(mysql));
}
else printf("Query made...\n");
res=mysql_use_result(mysql);
for(r=0;r<=mysql_field_count(mysql);r++){
row=mysql_fetch_row(res);
if(row<0) break;
for(t=0;t<mysql_num_fields(res);t++){
printf("%s ",row[t]);
}
printf("\n");
}
mysql_close(mysql);
return 0;
}
gdb liefert hierzu
Program received signal SIGSEGV, Segmentation fault.
0xb7d200e7 in memset () from /lib/libc.so.6
(gdb) backtrace
#0 0xb7d200e7 in memset () from /lib/libc.so.6
#1 0xb7e0e70a in mysql_init () from /usr/lib/libmysqlclient.so.15
#2 0x08048742 in main ()
Hmm, und was sagt uns das ?
Dass memset(), welches von mysql_init() aufgerufen wurde, welches
wiederum von main() aufgerufen wurde, auf einen ungültigen
Speicherbereich zugreift. Der Grund ist, dass du für mysql keinen
Speicher reserviert hast, mysql_init aber davon ausgeht dass es sich um
einen gültigen Zeiger handelt. Die Lösung hat dir Niquo schon verraten,
und sie steht auch in der Dokumentation zu mysql_init(): "If mysql is a
NULL pointer, the function allocates, initializes, and returns a new
object." Du musst den Zeiger also mit 0 (bzw. dem Makro NULL, zur
besseren optischen Unterscheidung zwischen Integern und Zeigern)
initialisieren:
Da war die erste Version besser. Die zweite verwendet einen
undefinierter Pointer (=> crash in memset). Entweder Platz übergeben
(1.Version) oder NULL (Niquo).
Danke für die Hilfe, sowie ich
MYSQL *mysql = 0;
verwende erhalte ich folgendes:
Program received signal SIGSEGV, Segmentation fault.
0xb7dd5c54 in mysql_real_connect () from /usr/lib/libmysqlclient.so.15
(gdb) backtrace
#0 0xb7dd5c54 in mysql_real_connect () from
/usr/lib/libmysqlclient.so.15
#1 0x0804878c in main ()
(gdb)
Was ich nicht verstehe ist, dass dies alles Beispiel-codes von MySQL
Seiten sind, die können doch nicht völlig "daneben" sein ?!?
Ok, vielen Dank, hab´s endlich zum Laufen gebracht, war nach dem MYSQL
°pmysql=NULL Problem noch ein anderer segfault Fehler im obigen code.
Vielen Dank an alle !