Verwirrender Fehler??? segmentation fault
-
Hallo erstmal,
Ich habe da ein Problem mit meinem Programm, vorweg ich bin ein relativer anfänger, vielleicht ist es nicht die beste art es zu machen, aber entspricht meinen fähigkeiten. Deshalb bin ich für Vorschläge zur allgemeinen Programm verbesserung offen.
char *str[41], *query, *ptr; unsigned long size; char nombre[50], materno[50], paterno[50], departamento[50], provincia[50], seccion[50], avenida[50]; char pasaporte[2], l_pais[50], l_departamento[50], l_provincia[50], l_localidad[50], fecha_nacimiento[11], sexo[2]; char *nota; char telefono[50], nr_identification[50], curso[50]; *curso = NULL; GetWindowText(hEditPaterno2, paterno, 49); if( (ptr = strchr(paterno, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditMaterno2, materno, 49); if( (ptr = strchr(materno, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditNombre2, nombre, 49); if( (ptr = strchr(nombre, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditCelular3, telefono, 49); if( (ptr = strchr(telefono, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditDepartamento3, departamento, 49); if( (ptr = strchr(departamento, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditProvincia3, provincia, 49); if( (ptr = strchr(provincia, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditMunicipio3, seccion, 49); if( (ptr = strchr(seccion, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditCalle3, avenida, 49); if( (ptr = strchr(avenida, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditIdentification2, nr_identification, 49); if( (ptr = strchr(nr_identification, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ if (SendMessage(hRadioCi2, BM_GETCHECK, 0, 0) == BST_CHECKED) strcpy(pasaporte, "C"); else if (SendMessage(hRadioPas2, BM_GETCHECK, 0, 0) == BST_CHECKED) strcpy(pasaporte, "P"); else if (SendMessage(hRadioLm2, BM_GETCHECK, 0, 0) == BST_CHECKED) strcpy(pasaporte, "L"); else strcpy(pasaporte, "0"); GetWindowText(hEditPais2, l_pais, 49); if( (ptr = strchr(l_pais, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditDepartamento2, l_departamento, 49); if( (ptr = strchr(l_departamento, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditProvincia2, l_provincia, 49); if( (ptr = strchr(l_provincia, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ GetWindowText(hEditLocalidad2, l_localidad, 49); if( (ptr = strchr(l_localidad, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ if (!(GetWindowText(hEditNacimiento_fe2, fecha_nacimiento, 49))==NULL) { if( (ptr = strchr(fecha_nacimiento, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ } else strcpy(fecha_nacimiento, "1999.12.12"); if (SendMessage(hRadioFe2, BM_GETCHECK, 0, 0) == BST_CHECKED) strcpy(sexo, "F"); else if (SendMessage(hRadioMa2, BM_GETCHECK, 0, 0) == BST_CHECKED) strcpy(sexo, "M"); else strcpy (sexo, "0"); nota = (char *) malloc(GetWindowTextLength(hEditNota)+1); GetWindowText(hEditNota, nota, (GetWindowTextLength(hEditNota)+1)); if( (ptr = strchr(nota, '\n')) != NULL) *ptr = '\0'; /* newline durch \0 ersetzen */ unsigned long list; list = SendMessage(hListCurso, LB_GETCURSEL, 0, 0); SendMessage(hListCurso, LB_GETTEXT, list, (LPARAM)curso); char puffer[15]; GetWindowText(hButtonSave, puffer, 14); if (!(strcmp(puffer, "Guardar"))) { str[0]= "INSERT INTO alumnos (nombre, departamento, provincia, seccion, avenida, pasaporte, l_pais, l_departamento, l_provincia, l_localidad, sexo, nota, telefono, nr_identification, fecha_nacimiento, curso) VALUES ('"; str[1] = (char *)malloc(strlen(paterno)+1); strcpy(str[1], paterno); str[2] = " "; str[3] = (char *) malloc(strlen(materno)+1); strcpy(str[3], materno); str[4] = " "; str[5] = (char *) malloc(strlen(nombre)+1); strcpy(str[5], nombre); str[6] = "', '"; str[7] = (char *) malloc(strlen(departamento)+1); strcpy(str[7], departamento); str[8] = "', '"; str[9] = (char *) malloc(strlen(provincia)+1); strcpy(str[9], provincia); str[10] = "', '"; str[11] = (char *) malloc(strlen(seccion)+1); strcpy(str[11], seccion); str[12] = "', '"; str[13] = (char *) malloc(strlen(avenida)+1); strcpy(str[13], avenida); str[14] = "', '"; str[15] = (char *) malloc(strlen(pasaporte)+1); strcpy(str[15], pasaporte); str[16] = "', '"; str[17] = (char *) malloc(strlen(l_pais)+1); strcpy(str[17], l_pais); str[18] = "', '"; str[19] = (char *) malloc(strlen(l_departamento)+1); strcpy(str[19], l_departamento); str[20] = "', '"; str[21] = (char *) malloc(strlen(l_provincia)+1); strcpy(str[21], l_provincia); str[22] = "', '"; str[23] = (char *) malloc(strlen(l_localidad)+1); strcpy(str[23], l_localidad); str[24] = "', '"; str[25] = (char *) malloc(strlen(sexo)+1); strcpy(str[25], sexo); str[26] = "', '"; str[27] = (char *) malloc(strlen(nota)+1); strcpy(str[27], nota); str[28] = "', '"; str[29] = (char *) malloc(strlen(telefono)+1); strcpy(str[29], telefono); str[30] = "', '"; str[31] = (char *) malloc(strlen(nr_identification)+1); strcpy(str[31], nr_identification); str[32] = "', '"; str[33] = (char *) malloc(strlen(fecha_nacimiento)+1); strcpy(str[33], fecha_nacimiento); str[34] = "', '"; str[35] = (char *) malloc(strlen(curso)+1); strcpy(str[35], curso); str[36] = "');"; for (int i=0; i < 37; i++) { size += strlen(str[i]); } query = (char *) malloc(size + 1); strcpy(query, str[0]); for(int i = 1; i < 37; i++) { strcat(query, str[i]); } mysql_real_query(my, query, strlen(query)); if (mysql_errno(my) != 0) { MessageBox(NULL, mysql_error(my), "Error", WS_VISIBLE ); } else { return true; } } /* else if (!(strcmp(puffer, "Cambiar"))) { str[0] = "update alumnos set nombre = '"; str[1] = (char *)malloc(strlen(paterno)+1); strcpy(str[1], paterno); str[2] = " "; str[3] = (char *) malloc(strlen(materno)+1); strcpy(str[3], materno); str[4] = " "; str[5] = (char *) malloc(strlen(nombre)+1); strcpy(str[5], nombre); str[6] = "', departamento = '"; str[7] = (char *) malloc(strlen(departamento)+1); strcpy(str[7], departamento); str[8] = "', provinica = '"; str[9] = (char *) malloc(strlen(provincia)+1); strcpy(str[9], provincia); str[10] = "', seccion = '"; str[11] = (char *) malloc(strlen(seccion)+1); strcpy(str[11], seccion); str[12] = "', avenida = '"; str[13] = (char *) malloc(strlen(avenida)+1); strcpy(str[13], avenida); str[14] = "', pasaporte = '"; str[15] = (char *) malloc(strlen(pasaporte)+1); strcpy(str[15], pasaporte); str[16] = "', l_pais = '"; str[17] = (char *) malloc(strlen(l_pais)+1); strcpy(str[17], l_pais); str[18] = "', l_departamento = '"; str[19] = (char *) malloc(strlen(l_departamento)+1); strcpy(str[19], l_departamento); str[20] = "', l_provincia = '"; str[21] = (char *) malloc(strlen(l_provincia)+1); strcpy(str[21], l_provincia); str[22] = "', l_localidad = '"; str[23] = (char *) malloc(strlen(l_localidad)+1); strcpy(str[23], l_localidad); str[24] = "', sexo = '"; str[25] = (char *) malloc(strlen(sexo)+1); strcpy(str[25], sexo); str[26] = "', nota = '"; str[27] = (char *) malloc(strlen(nota)+1); strcpy(str[27], nota); str[28] = "', telefono = '"; str[29] = (char *) malloc(strlen(telefono)+1); strcpy(str[29], telefono); str[30] = "', nr_identification = '"; str[31] = (char *) malloc(strlen(nr_identification)+1); strcpy(str[31], nr_identification); str[32] = "', fecha_nacimiento = '"; str[33] = (char *) malloc(strlen(fecha_nacimiento)+1); strcpy(str[33], fecha_nacimiento); str[34] = "', curso = '"; str[35] = (char *) malloc(strlen(curso)+1); strcpy(str[35], curso); str[36] = "' where nombre = '"; str[37] = (char *) malloc(strlen(nombre)+1); strcpy(str[37], nombre); str[38] = "' or nr_identification = '"; str[39] = (char *) malloc(strlen(nr_identification)+1); strcpy(str[39], nr_identification); str[40] = "';"; for (int i=0; i < 41; i++) { size += strlen(str[i]); } query = (char *) malloc(size + 1); strcpy(query, str[0]); for(int i = 1; i < 41; i++) { strcat(query, str[i]); } mysql_real_query(my, query, strlen(query)); if (mysql_errno(my) != 0) { MessageBox(NULL, mysql_error(my), "Error", WS_VISIBLE ); } else { return true; } }*/ } else { MessageBox(NULL, "Es wurden keine Daten eingegeben!", "Fehler", WS_VISIBLE); } return false; }
Kurz zum Programm:
Es handelt sich hier um ein Programm zur verwaltung einer Datenbank. Gearbeitet wird mit C, sowie WIN32API und MYSQL. Da sich der Fehler aber nur auf den C-Quellcode-Teil bezieht, denke ich das ich Richtig bin.
Das Programm lädt von einem Formular die daten für die entsprechenden Variablen, Name wird in nombre abgespeichert usw. Dann wird geguckt welche art von Formular es ist, ein Formular um einen neuen schüler hinzu zufügen oder daten eines schülers zu ändern, dafür benutze ich das selbe formular und der button zum abspeichern dient mir mit seinem namen als eine art "Flag". Dann wird der String erstellt mit dem Entweder, je nachfall, die daten geändert werden oder hinzugefügt werden... So viel zum Programm.Der Fehler:
Solange wie ich den jetzt komentierten bereich nicht mit in den Quellcode mitaufnehme, funktioniert das Programm, ich kann einen schüler hinzufügen. Sobald ich aber die kommentar zeichen entfernen, und somit dieser Teil bestandteil des Programms wird, erhalte ich einen fehler. Den "Segmentation fault" fehler. Seltsamer weiße aber bei beiden Fällen
Der erste teil der vorher noch funktionierte, funktioniert nicht mehr.
Beim debugen konnte ich den fehler auf diese zeile beschränken.strcpy(query, str[0]); for(int i = 1; i < 37; i++) { strcat(query, str[i]); }
Im ersten Teil. Problem soll es laut debuger mit der funktion strcat() geben.
Aber wieso jetzt aufeinmal? der zweite fall tritt nicht mal inkraft sowie wenn überhaupt nach der funktion.Ich wäre für jede Art von hilfe und tipps dankbar.
-
Welchen Wert hat size in Zeile 173?
Und was passiert, wenn du den Speicher mit malloc nicht bekommst?
Nebenbei optimiert der Compiler, die Teile die gleich sind, sind durchaus auch nur einmal vorhanden. (Der Compiler darf Spaghetticode machen).
-
Segmentation fault (Speicherzugriffsverletzung) lässt sich super debuggen. Einfach wenn das Programm abstürzt den BackTrace angucken (so geht es zumindestens bei mir mit dem gdb) und schon weißt du wo es genau passiert.
-
Das ist ja genial!!! Ich zerbreche mir seit tagen den kopf!!! und du findest in wenigen sekunden den fehler
ja size ist der fehler, weil size mit keinem wert vorher aufgerufen wird, hat es einen abstrakten wert der dann mit den werten noch dazu addiert wird
size = 0;
Löst alle meine problemeVielen vielen Dank für die schnelle hilfe
-
Der Wert war wohl so groß, das du beim zweiten Versuch keinen Speicher mehr bekommen hast.
In diesem Fall gibt malloc NULL zurück.Und das ist der zweite Fehler: Du hast die Rückgabewerte von malloc nicht überprüft.
-
Dein Quellcode ist tatsächlich sehr grausam. Du musst die Strings nicht zeichenweise zusammenbauen. Nimm dir ein Array der groß genug ist und benutz z.B. sprintf. Außerdem reservierst du sehr oft Speicher mit malloc. Ich hoffe, du gibst auch alles mit free wieder frei?
Außerdem solltest du Variablennamen in Englisch halten.
-
ggggg schrieb:
Außerdem solltest du Variablennamen in Englisch halten.
Ich komme mir gerade vor, wie der Petunientopf.
Warum soll man sich einschränken?
Zudem passen die Variablennamen zu den Datenbankfeldern.
-
DirkB schrieb:
ggggg schrieb:
Außerdem solltest du Variablennamen in Englisch halten.
Ich komme mir gerade vor, wie der Petunientopf.
Warum soll man sich einschränken?
Zudem passen die Variablennamen zu den Datenbankfeldern.Weil es für aussenstehende nicht mehr so gut nachvollziehbar ist. Hier war es noch gut möglich, da sowohl die deutsche als auch die verwendete Sprache ähnliche Wurzeln haben.
Anders sieht das schon hier aus:
char imja[50], mama[50], otec[50], ulizja[50], provinzja[50]; char *komenta;
Hier kann man schon schwerer ableiten und ich bin mir sicher, dass es bei komplexeren Dingen auch bei Sprachen schwierig wird die dem Deutschen ähnlich sind.
Insofern tut er sich selber damit auch keinen gefallen. Sollte er mal wieder Hilfe brauchen, macht er es den Helfern dadurch noch schwerer.
Das ist also keine Eischränkung, sondern eine Eröffnung!
-
Ja die namen sind in spanisch gehalten weil das mit den felder in der datenbank übereinstimmt und dieses Formular vorher auf einem Ofizielenpapier stand und deswegen einfacher war.
Ne frage zu malloc!!! Wird der speicher nicht automatisch wieder freigegeben wenn die funktion verlassen wird???
Über den langen array hatte ich auch schon nachgedacht, da aber nicht immer alle felder besetzt sind und die länge von namen, kurse usw. sehr varieren kann, fand ich es sicherer und speicher ärmer es dynamisch zu erstellen.
-
malloc hat keine Information darüber, aus welcher Funktion du es aufrufst.
Du musst alle Speicherbereiche einzeln perfree()
freigeben.
-
ach das ist gut zu wissen... ok vielen dank, das wird verbessert