Segmentation fault bei Linux

Gast #509134
Lesenswert?

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 !
Gast #509268
Lesenswert?

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);
Gast #509332
Lesenswert?

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 ?
Admin Persönliche Seite #509342
Lesenswert?

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;
Gast #509358
Lesenswert?

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 ?!?
Gast #509432
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren