Free Zeiger auf Zeiger
-
Hallo,
Ich habe mein Problem in diesem Forum gesucht aber nichts gefunden deswegen möchte ich einen neuen Thema erstellen. Ich habe folgende Codeabschnitt und möchte den Speicher mit free wieder freigeben, allerdings bekomme ich immer das Signal SIGSEGV (Segmentation Violation), wenn ich das Program mit Ctrl+C beenden möchte. Ich entwickle das auf dem Raspberry Pi (arm-gnu-none-eabi-gcc)#define CLEANUP(l, v, d, mq1, mq2, mqn1, mqn2) \ l=0; \ if(mq1 > -1) { mq_close(mq1); } \ if(mq2 > -1) { mq_close(mq2); } \ if(strcmp(mqn1, "") != 0) { mq_unlink(mqn1); }\ if(strcmp(mqn2, "") != 0) { mq_unlink(mqn2); }\ if(v->a != NULL) { free(v->a); v->c = NULL; }\ if(v->b != NULL) { free(v->b); v->c = NULL; }\ if(v->c != NULL) { free(v->c); v->c = NULL; }\ if(v != NULL) { free(v); v = NULL; } typedef struct vector { double x; double y; double z; } vec_t; typedef struct vectors { vec_t *a; vec_t *b; vec_t *c; } vecs_t; vecs_t *vectors; int main(int argc, char **argv) { // andere vaiablen wie l, mq1, mq2, mqn1, mqn2, sa1 ... data ... sa.sa_handler = SignalHandler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sa1 = sigaction(SIGINT, &sa, NULL); sa2 = sigaction(SIGBUS, &sa, NULL); sa3 = sigaction(SIGABRT, &sa, NULL); sa4 = sigaction(SIGSEGV, &sa, NULL); if( (sa1 < 0) || (sa2 < 0) || (sa3 < 0) || (sa4 < 0) ) { perror("Signal(s) could not be regsitered."); exit(EXIT_FAILURE); } if ( (vectors = malloc(sizeof(*vectors) ) ) == NULL) { perror("Cannot allocate memory for variables."); exit(EXIT_FAILURE); } if( (vectors->a = (vec_t *)calloc(3, sizeof(double))) == NULL ) { perror("Cannot allocate memory for gyroscope vector."); free(vectors); exit(EXIT_FAILURE); } if( (vectors->b = (vec_t *)calloc(3, sizeof(double))) == NULL ) { perror("Cannot allocate memory for accelerometer vector."); free(vectors->a); free(vectors); exit(EXIT_FAILURE); } if( (vectors->c= (vec_t *)calloc(3, sizeof(double))) == NULL ) { perror("Cannot allocate memory for magnetometer vector."); free(vectors->a); free(vectors->b); free(vectors); exit(EXIT_FAILURE); } while(1) { sleep(1); } } // main static void SignalHandler(int sig) { char *errorString = NULL; switch(sig) { case SIGINT: errorString = "\nProgramm terminated by user (SIGINT)\n"; break; case SIGBUS: errorString = "\nBus error. (SIGBUS)\n"; break; case SIGABRT: errorString = "\nAbort signal received. (SIGABRT)\n"; break; case SIGSEGV: errorString = "\nSegmentation violation signal received. (SIGSEGV)\n"; break; default: errorString = "\nUnknown error.\n"; break; } fprintf(stderr, errorString); CLEANUP(loop, vectors, data, mqd1, mqd2, mq_name1, mq_name2); }
-
#define CLEANUP(l, v, d, mq1, mq2, mqn1, mqn2) \ l=0; \ if(mq1 > -1) { mq_close(mq1); } \ if(mq2 > -1) { mq_close(mq2); } \ if(strcmp(mqn1, "") != 0) { mq_unlink(mqn1); }\ if(strcmp(mqn2, "") != 0) { mq_unlink(mqn2); }\ if(v->a != NULL) { free(v->a); v->c = NULL; }\ if(v->b != NULL) { free(v->b); v->c = NULL; }\ if(v->c != NULL) { free(v->c); v->c = NULL; }\ if(v != NULL) { free(v); v = NULL; }
Du überschreibst v->c mit NULL und versuchst danach v->c mit free freizugeben.
-
Bzw. gibst es nicht frei.
-
fwbp34 schrieb:
#define CLEANUP(l, v, d, mq1, mq2, mqn1, mqn2) \ l=0; \ if(mq1 > -1) { mq_close(mq1); } \ if(mq2 > -1) { mq_close(mq2); } \ if(strcmp(mqn1, "") != 0) { mq_unlink(mqn1); }\ if(strcmp(mqn2, "") != 0) { mq_unlink(mqn2); }\ if(v->a != NULL) { free(v->a); v->c = NULL; }\ if(v->b != NULL) { free(v->b); v->c = NULL; }\ if(v->c != NULL) { free(v->c); v->c = NULL; }\ if(v != NULL) { free(v); v = NULL; }
Du überschreibst v->c mit NULL und versuchst danach v->c mit free freizugeben.
Danke für die Antwort aber habe ich übersehen oder nicht verstanden?
Achsooo, Ich habe einfach Kopiefehler gemacht wenn ich disen Thread erstellt habe. Im Originalcode ist es naturlich korrekt.
if(v->a != NULL) { free(v->a); v->a = NULL; }\ if(v->b != NULL) { free(v->b); v->b = NULL; }\ if(v->c != NULL) { free(v->c); v->c = NULL; }\
Aber, wenn ich versuchsweise die if Anweisungen lösche, bekomme ich auch gleiche Fehler. Es gibt gar keine Änderung.
#define CLEANUP(l, v, d, mq1, mq2, mqn1, mqn2) \ l=0; \ mq_close(mq1); \ mq_close(mq2); \ mq_unlink(mqn1); \ mq_unlink(mqn2); \ free(v->a); v->a = NULL; \ free(v->b); v->b = NULL; \ free(v->c); v->c = NULL; \ free(v); v = NULL;
[/code]
-
Ich könnte mir vorstellen das mit v etwas nicht stimmt, kannst es ja mal so probieren.
#define CLEANUP(l, v, d, mq1, mq2, mqn1, mqn2) \ l=0; \ if(mq1 > -1) { mq_close(mq1); } \ if(mq2 > -1) { mq_close(mq2); } \ if(strcmp(mqn1, "") != 0) { mq_unlink(mqn1); }\ if(strcmp(mqn2, "") != 0) { mq_unlink(mqn2); }\ if(v)\ {\ if(v->a != NULL) { free(v->a); }\ if(v->b != NULL) { free(v->b); }\ if(v->c != NULL) { free(v->c); }\ free(v); v = NULL;\ }
-
Gibt es irgendeinen speziellen Grund, von dem ich nichts weiß, dass du ein CLEANUP-Makro benutzt?
-
Schau mal mit dem Debugger (oder mit
if (vectors == NULL) puts("vecotr == NULL");
) im SignalHandler nach, ob der nicht mehrmals aufgerufen wird.
-
Ich verwende CLEANUP merhmals im Program, aber nur in Fehlerfällen. In den Fehlerfällen gebe ich einige Fehlertexten am Bildschirrm bevor CLEANUP aus. Der Grund warum ich ein Makro benutze ist so, Im Programm gibt es viele Zeiger, die auf Fehlerfällen oder beim Schluss des Programms immer freigegeben werden müssen. Eine Funktion statt Makro habe ich auch versucht aber Die Fehlermeldung kommt immer noch.
Ich habe folgende Code jetzt versucht:
... if(v) \ { \ free(v->gyro); v->gyro = NULL;\ free(v->accel); v->accel = NULL;\ free(v->magnet); v->magnet = NULL;\ free(v); v = NULL; \ }
und auch
if (vectors == NULL) puts("vector == NULL");
in SignalHandler probiert, nun bekomme ich den Text vector == NULL und den Text "Segmentation violation signal received. (SIGSEGV)" in einer endlos Schleife.
-
Jetzt funktioniert die Code wie erwartet
Ich habe einfach exit-Aufruf in der SignalHandler hinzugefügt und die Funktion wie folgt geändert.
static void SignalHandler(int sig) { char errorString[64]; switch(sig) { case SIGINT: strcpy(errorString, "\nProgramm terminated by user (SIGINT)\n"); if(vectors == NULL) puts("vector == NULL"); break; case SIGBUS: strcpy(errorString, "\nBus error. (SIGBUS)\n"); break; case SIGABRT: strcpy(errorString, "\nAbort signal received. (SIGABRT)\n"); break; case SIGSEGV: strcpy(errorString, "\nSegmentation violation signal received. (SIGSEGV)\n"); if(vectors == NULL) puts("vector == NULL"); break; default: strcpy(errorString, "\nUnknown error.\n"); break; } fprintf(stderr, errorString); CLEANUP(loop, vectors, data, mqd1, mqd2, mq_name1, mq_name2); exit (EXIT_FAILURE); // das habe ich hinzugefügt. }
-
kahlenberg schrieb:
..und auch
if (vectors == NULL) puts("vector == NULL");
in SignalHandler probiert, nun bekomme ich den Text vector == NULL und den Text "Segmentation violation signal received. (SIGSEGV)" in einer endlos Schleife.
Kannst du dir denn jetzt auch denken, warum du dann den SIGSEGV bekommen hast?
-
DirkB schrieb:
Kannst du dir denn jetzt auch denken, warum du dann den SIGSEGV bekommen hast?
Natürlich...
Danke für die Antwort und Mühe.