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 !
als erstes würde ich mal versuchen rauszufinden an welche rStelle der Fehlerpassiert. Schonmal den gdb angeworfen?
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:
1 | MYSQL *mysql = NULL; |
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 ?!?
Habe A.Ks post erst jetzt gelesen - und bin nun endgültig verwirrt, was passt denn nun ?
Lies Dir die Docs von MySQL durch! Es gehen beide Varianten von mysql_init. Aber nur wenn man sie auch richtig benutzt!!! Also enweder:
1 | MYSQL mysql; |
2 | mysql_init(&mysql); |
oder:
1 | MYSQL *pmysql; |
2 | pmysql = mysql_init(NULL); |
3 | if(!pmysql) { |
4 | // ERROR
|
5 | }
|
bzw.
1 | MYSQL *pmysql = NULL; |
2 | pmysql = mysql_init(pmysql); |
3 | if(!pmysql) { |
4 | // ERROR
|
5 | }
|
CU Frank
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 !
>anderer segfault ...
Ja vermutlich beim printf :-)
Besser wär wohl gewesen:
1 | printf("%s ", row[t] ? row[t] : "<NULL>"); |
Steht aber auch so direkt als Beispiel in der Docu zu mysql_fetch_row. CU
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.