Speicherzugriffsfehler: Warum?
-
Hey.
Ich habe ein Problem mit meinem Programm. Es funktioniert alles soweit, abgesehen von der Funktion "Approx". Ich hänge am Ende mal den Programmquellcode an.Dort erhalte ich einen Speicherzugriffsfehler.
Man kann hier auf Folie 11 den Algorithmus einsehen, der in Approx implementiert werden soll:
http://www.math.tu-bs.de/mo/teaching/SS2010/fpraktikum/printVL_2010-04-20.pdf
Die Meldungen hängen wohl (denke ich) an den mallocs in den Zeilen 495 - 498, daraus entstehen dann die Probleme in den Zeilen 504 - 507. Ich rufe diese mallocs in einer Schleife auf. Ich weiß, dass das ja eigtl nicht geht/so sein sollte? Aber das Problem ist, dass erst in dieser Schleife die Größe newRSPI->n festgelegt/festgestellt wird und ich somit vorher keinen Speicher alloziieren kann?
Kann mir jemand weiterhelfen?#include <stdio.h> #include <stdlib.h> typedef struct { int index; double efficiency; } EFF; typedef struct { int C; /* Capacity */ int *w; /* weight */ int *p; /* profit */ int n; /* number of elements */ char *x; /* solution, 0 = dont pack, 1 = pack, 2 = dont know yet */ EFF *effundindex; } RSPinstance; RSPinstance *RSPinstanceCopy(RSPinstance *RSPI){ /* copy the RSP-Instance */ RSPinstance *newRSPI = (RSPinstance*) malloc(sizeof(RSPinstance)); int i; newRSPI->C = RSPI->C; newRSPI->n = RSPI->n; newRSPI->x = (char*) malloc(sizeof(char) * newRSPI->n); newRSPI->p = (int*) malloc(sizeof(int) * newRSPI->n); newRSPI->w = (int*) malloc(sizeof(int) * newRSPI->n); for (i = 0; i < RSPI->n; i++){ newRSPI->p[i] = RSPI->p[i]; newRSPI->w[i] = RSPI->w[i]; newRSPI->x[i] = RSPI->x[i]; } return newRSPI; } RSPinstance *ReadData(FILE *instancefile){ /* open file */ RSPinstance *instance; int i; /* fill instance */ instance = malloc(sizeof *instance); if (!instance){ fprintf(stderr, "Out of memory\n"); fclose(instancefile); return 0; } if (fscanf(instancefile, "%d", &instance->C) != 1){ fprintf(stderr, "Wrong instance format in parameter C\n"); free(instance); fclose(instancefile); return 0; } if (fscanf(instancefile, "%d", &instance->n) != 1){ fprintf(stderr, "Wrong instance format in paramenter n\n"); free(instance); fclose(instancefile); return 0; } if (instance->n <= 0){ fprintf(stderr, "Wrong instance format in parameter n must not be <= 0\n"); free(instance); fclose(instancefile); return 0; } /* allocate memory for the elements of the instance */ instance->w = (int*) malloc(sizeof(int) * instance->n); instance->p = (int*) malloc(sizeof(int) * instance->n); instance->x = (char*) malloc(sizeof(char) * instance->n); /*if (!instance->w || !instance->p || !instance->x){ fprintf(stderr, "Out of memory\n"); free(instance->w); free(instance->p); free(instance->x); free(instance); fclose(instancefile); return 0; } */ for (i = 0; i < instance->n; i++) { if (fscanf(instancefile, "%d %d", &instance->w[i], &instance->p[i]) != 2) { fprintf(stderr, "Wrong instance format in element %d\n", i + 1); free(instance->w); free(instance->p); free(instance); fclose(instancefile); return 0; } } fclose(instancefile); for (i = 0; i < instance->n; i++) instance->x[i] = 2; /* we dont know what to pack yet */ return instance; } void printInstance(RSPinstance *RSPI){ int i; printf("Printing RSP instance\n"); printf("Capacity: %d\n", RSPI->C); printf("Number of Elements: %d\n", RSPI->n); for (i = 0; i < RSPI->n; i++) printf("Element %d: Weight: %d, Profit: %d\n", i, RSPI->w[i], RSPI->p[i]); } RSPinstance *Preprocessing(RSPinstance *RSPI, int *Jm, int *Jp, int *J0y, int *sumW, int *sumP,FILE *Ausgabe){ /* simplify an RSP-instance */ RSPinstance *newRSPI; int j,k, *J0, *J1; int nJp, nJm, nJ0y; /* variables to count the number of elements in the J_+, J_-, and J_0¯y sets*/ int sumJ1Jm, sumJ; /* sum over the weights in the J sets*/ int nFixed0, nFixed1; /* variables to count the number of fixed variables, total weight and total profit during preprocessing*/ /* PREPROCESSING */ /* 1. if n <= 0 => EXIT and return NULL,because instance does not make sense */ if (RSPI->n <= 0){ free(newRSPI); return NULL; } J0 = (int*) calloc( RSPI->n, sizeof( int)); J1 = (int*) calloc( RSPI->n, sizeof( int)); newRSPI = malloc( sizeof( RSPinstance)); sumJ1Jm = 0; nJp = 0; nJm = 0; nFixed0 = 0; nFixed1=0; for (j = 0; j < RSPI->n; j++) { /* 2. For all j element of J_0 := {j element [n] | p_j <= 0, w_j >= 0}: fix x_j = 0, as those elements would never be packed */ if (RSPI->p[j] <= 0 && RSPI->w[j] >= 0) { RSPI->x[j] = 0; nFixed0++; J0[ j] = 1; } /* 3. For all j element of J_1 := {j element [n] | p_j >= 0, w_j <= 0}: fix x_j = 1, as those elements can always be packed gainfully */ if (RSPI->p[j] >= 0 && RSPI->w[j] <= 0) { RSPI->x[j] = 1; J1[ j] = 1; nFixed1++; *sumW = *sumW + RSPI->w[j]; *sumP = *sumP + RSPI->p[j]; sumJ1Jm = sumJ1Jm + RSPI->w[j]; } /* 4. transformation of variables */ if (RSPI->p[j] < 0 && RSPI->w[j] < 0) { Jm[j] = 1; nJm++; sumJ1Jm = sumJ1Jm + RSPI->w[j]; } if (RSPI->p[j] > 0 && RSPI->w[j] > 0) { Jp[j] = 1; nJp++; } } /* 5. if the capacity C < sum over the weights in the union of J_1 and J_m => EXIT as the instance has no valid solution */ if (RSPI->C < sumJ1Jm) { free(J0); free(J1); free(Jp); free(Jm); free(J0y); free(newRSPI); return NULL; } /* 6. for all j element of J_0¯y : fix y_j = 0 => accordingly fix x_j, as those objects violate the capacity restriction */ sumJ = 0; nJ0y = 0; for (j=0; j < RSPI->n; j++) { /* find out if the element is in J_0¯y */ if (abs(RSPI->w[j]) > RSPI->C - sumJ1Jm) { /* fix x_j = 1 - y_j = 1 (pack) if j is element of J_- */ if (Jm[j]==1) { RSPI->x[j]=1; nFixed1++; *sumW = *sumW + RSPI->w[j]; *sumP = *sumP + RSPI->p[j]; nJ0y++; J0y[j]=1; } /* fix x_j = y_j = 0 (dont pack) if j is element of J_+ */ else if (Jp[j]==1) { RSPI->x[j]=0; nFixed0++; nJ0y++; J0y[j]=1; } } } /* 7. if the sum over the weights of the elements j in J < Capacity C - the sum of the weights of the elements of the union of J_1 and J_- => fix y_j= 1 and x_j accordingly, as all objects left can either be packed gainfully or will not be packed */ /* sum over the weights of the elements j in J */ for (j=0; j < RSPI->n; j++) { if ((Jm[j]==1 || Jp[j]==1) && J0y[j]==0) sumJ = sumJ + abs(RSPI->w[j]); } if (sumJ <= (RSPI->C - sumJ1Jm)) { for(j=0; j < RSPI->n; j++) { /* fix x_j = 1 - y_j = 0 (dont pack) if j is element of J_- */ if (Jm[j]==1 && J0y[j]==0) { RSPI->x[j]=0; nFixed0++; } /* fix x_j = y_j = 1 (pack) if j is element of J_- */ else if (Jp[j]==1 && J0y[j]==0) { RSPI->x[j]=1; nFixed1++; *sumW = *sumW + RSPI->w[j]; *sumP = *sumP + RSPI->p[j]; } } free(J0); free(J1); free(Jp); free(Jm); free(J0y); fprintf(Ausgabe,"\nPREPROCESSING:\n\n"); fprintf(Ausgabe,"The problem is optimally solved\n"); fprintf(Ausgabe,"Number of variables fixed to 0: %i\nNumber of variables fixed to 1: %i\n", nFixed0, nFixed1); fprintf(Ausgabe,"Total weight of objects packed during preprocessing: %i\nTotal profit of objects packed during preprocessing: %i\n", *sumW, *sumP); newRSPI->n = 0; return (newRSPI); } /* construct residual instance */ newRSPI->C = RSPI->C - sumJ1Jm; newRSPI->n = nJm + nJp - nJ0y; newRSPI->x = (char*) malloc(sizeof(char) * newRSPI->n); newRSPI->p = (int*) malloc(sizeof(int) * newRSPI->n); newRSPI->w = (int*) malloc(sizeof(int) * newRSPI->n); k =0 ; for (j=0; j < RSPI->n; j++) { if ((Jm[j]==1 || Jp[j]==1) && J0y[j]==0) { newRSPI->p[k] = abs(RSPI->p[j]); newRSPI->w[k] = abs(RSPI->w[j]); k++; } } fprintf(Ausgabe,"\nPREPROCESSING:\n\n"); fprintf(Ausgabe,"Residual capacity: %i.\n", newRSPI->C); fprintf(Ausgabe,"Number of variables fixed to 0: %i\nNumber of variables fixed to 1: %i\n", nFixed0, nFixed1); fprintf(Ausgabe,"Total weight of objects packed during preprocessing: %i\nTotal profit of objects packed during preprocessing: %i\n", *sumW, *sumP); free(J0); free(J1); return newRSPI; } void TransformSolution(RSPinstance *RSPI_org,RSPinstance *RSPI_residual,int *Jm, int *Jp, int *J0y) { int j, k; k = 0; /* transformation of x for j in J */ for (j=0; j < RSPI_org->n; j++) { /* if j is in J_- => x_j = 1 - x_residual_k */ if (Jm[j]==1 && J0y[j]==0) { RSPI_org->x[j] = 1 - RSPI_residual->x[k]; k++; } /* if j is in J_+ => x_j = x_residual_k */ else if (Jp[j]==1 && J0y[j]==0) { RSPI_org->x[j]= RSPI_residual->x[k]; k++; } } free(J0y); free(Jm); free(Jp); free(RSPI_residual->x); free(RSPI_residual->p); free(RSPI_residual->w); free(RSPI_residual); } int compare(void const *a, void const *b) { double aa = ((EFF *)a)->efficiency; double bb = ((EFF *)b)->efficiency; if (aa > bb) return -1; else if (bb > aa) return 1; else return 0; } void Greedy(RSPinstance *RSPI,int *W,int *L) { int j,i; int max,max_index; max=0; max_index=0; RSPI->effundindex = (EFF*) malloc(sizeof(EFF) * RSPI->n); /* construct array with efficiency and indices */ for (j=0; j < RSPI->n; j++) { (RSPI->effundindex[j]).efficiency= ((double)RSPI->p[j])/((double)RSPI->w[j]); (RSPI->effundindex[j]).index = j; /*printf("%lf Index: %i p: %d w: %d\n",(RSPI->effundindex[j]).efficiency,(RSPI->effundindex[j]).index,RSPI->p[j],RSPI->w[j]);*/ } qsort(RSPI->effundindex, RSPI->n, sizeof(EFF), compare); /* printf("\n\nSortiertes Array:\n"); for (j=0; j < RSPI->n; j++) { printf("%lf %i\n",(RSPI->effundindex[j]).efficiency,(RSPI->effundindex[j]).index); }*/ for (j=0; j < RSPI->n; j++) { if (*W+RSPI->w[(RSPI->effundindex[j]).index] <= RSPI->C ) { RSPI->x[(RSPI->effundindex[j]).index]=1; *W = *W + RSPI->w[(RSPI->effundindex[j]).index]; *L = *L + RSPI->p[(RSPI->effundindex[j]).index]; } if (max < RSPI->p[(RSPI->effundindex[j]).index] ) {max = RSPI->p[(RSPI->effundindex[j]).index]; max_index=j; } } if (*L < max) { for (i=0; i<RSPI->n;i++) { RSPI->x[(RSPI->effundindex[i]).index]=0;} *L=max; *W=RSPI->w[(RSPI->effundindex[max_index]).index]; RSPI->x[(RSPI->effundindex[max_index]).index]=1; } } void Approx(RSPinstance *RSPI,int *W,int *L) { int LA,z,r,i,k,j,min,max, max_index; struct node { //struct node *left; struct node *right; int data; }; struct node * new_list(){ struct node *new = (struct node*) malloc(sizeof(struct node)); new->data = -1; new->right = NULL; //new->left = new; return new; } struct node * insert_right(struct node *list, int data){ struct node *new = (struct node *) malloc(sizeof(struct node)); new->data = data; //new->left = list; new->right = list->right; list->right = new; //new->right->left = new; return new; } void print_all(struct node* list){ struct node *head = list; struct node *current = list; printf("%d ", head->data); while (head != (current = current->right)){ printf("%d ", current->data); } printf("\n"); } /* erstelle eine neue Liste: */ struct node *head = new_list(); struct node *current = head; max=0; min =0; max_index=0; RSPinstance *newRSPI; newRSPI = malloc( sizeof( RSPinstance)); for (i=0; i < RSPI->n; i++) { if (max < RSPI->p[i]) max = RSPI->p[i]; max_index=i; } RSPI->x[max_index]=1; LA = max; for (i=0; i < RSPI->n-1; i++) { for (j=i+1; j < RSPI->n; j++) {if ( (RSPI->w[i] + RSPI->w[j] <= RSPI->C)) { newRSPI->C = RSPI->C - (RSPI->w[i] + RSPI->w[j]); if (RSPI->p[i]<RSPI->p[j]) min=RSPI->p[i]; else min=RSPI->p[j]; newRSPI->n = 0; for (k=0; k < RSPI->n; k++) { if ((k!=j) && (k!=i) && (RSPI->p[k]<= min)) { if (newRSPI->C >= RSPI->w[k]) { newRSPI->n++; current = insert_right(current, k); /*printf("i: %i,j: %i,k: %i, w: %i\n", i+1, j+1, k, RSPI->w[current->data]);*/ } } } newRSPI->effundindex = (EFF*) malloc(sizeof(EFF) * newRSPI->n); newRSPI->x = (char*) malloc(sizeof(char) * newRSPI->n); newRSPI->p = (int*) malloc(sizeof(int) * newRSPI->n); newRSPI->w = (int*) malloc(sizeof(int) * newRSPI->n); r=0; current = head->right; while (current != NULL) { /*printf("w: %i, k: %i\n",RSPI->w[current->data], current->data);*/ newRSPI->w[r]=RSPI->w[current->data]; newRSPI->p[r]=RSPI->p[current->data]; (newRSPI->effundindex[r]).efficiency=((double)RSPI->p[current->data])/((double)RSPI->w[current->data]); (newRSPI->effundindex[r]).index=current->data; current = current->right; r++; } Greedy(newRSPI, W, L); if((RSPI->p[i] + RSPI->p[j] + *L) > LA) { LA = (RSPI->p[i] + RSPI->p[j] + *L); /* alle RSPI->x auf 0 setzen außer i und j */ for (z=0; z < RSPI->n; z++) { if (z==i || z==j) {RSPI->x[z]=1;} else {RSPI->x[z]=0;} } r=0; current = head->right; while (current != NULL) { RSPI->x[current->data]=newRSPI->x[r]; current = current->right; r++; } } } } } } int main(int argc, char *argv[]){ RSPinstance *RSPI, *RSPI_residual; int i, packed; int *Jm, *Jp, *J0y; int ZFW, TW, sumW, sumP, W, L; FILE *instancefile; FILE *Ausgabe; Ausgabe = fopen ("Ausgabe.txt", "w"); packed=0; W = 0; L = 0; sumW = 0; sumP = 0; ZFW=0; TW=0; if (argc != 3){ fprintf(stderr,"Wrong number of parameters!\n"); exit(-1); } instancefile = fopen( argv[1], "r"); if (NULL ==instancefile){ fprintf(stderr, "Failed opening file\n"); exit(-1); } RSPI = ReadData(fopen(argv[1], "r")); Jm = (int*) calloc(RSPI->n,sizeof(int)); Jp = (int*) calloc(RSPI->n,sizeof(int)); J0y = (int*) calloc(RSPI->n,sizeof(int)); /* call the preprocessing function */ RSPI_residual = Preprocessing( RSPI, Jm, Jp, J0y, &sumW, &sumP, Ausgabe); if (NULL == RSPI_residual) { fprintf( Ausgabe, "There is no valid solution\n"); exit( -1); } if (RSPI_residual->n != 0) { if (*argv[2]=='G') { fprintf(Ausgabe, "\n \nMODIFIED GREEDY ALGORITHM\n"); Greedy(RSPI_residual, &W, &L); } else if (*argv[2]=='A') { fprintf(Ausgabe, "\n \nAPPROX ALGORITHM\n"); Approx(RSPI_residual, &W, &L);} else {printf("Wrong parameter argument entered!"); exit(-1);} TransformSolution( RSPI, RSPI_residual, Jm, Jp, J0y); } fprintf(Ausgabe,"Indices of packed objects:\n"); for (i=0; i < RSPI->n; i++) { ZFW = ZFW + RSPI->p[i] * RSPI->x[i]; TW = TW + RSPI->w[i] * RSPI->x[i]; packed = packed + RSPI->x[i]; if(RSPI->x[i]==1) { fprintf(Ausgabe,"%i\t", i+1); } } if (Ausgabe != NULL) { fprintf (Ausgabe, "\nNumber of packed objects: %i\n\nPROFIT: %i\nWEIGHT: %i", packed, ZFW, TW); fclose (Ausgabe); } printf("\n"); exit( 0); }
-
und du erwartest, dass wir uns den ganzen Code anschauen? Wieviel willst du dafür zahlen?
Schon mal von Debugger gehört? Wenn du GNU/Linux oder ein UNIX-like System hast, kannst du valgrind verweden. Ich glaube, es gibt sogar einen Windows-Port, aber da bin ich mir nicht sicher.
-
Natürlich brauch sich niemand den ganzen Code anschauen. Ich habe ihn nur gepostet, falls jemand den Zusammenhang sehen möchte. Es geht um die Funktion Approx und das Problem hängt an den oben genannten Zeilen, das habe ich über valgrind erfahren. Ich weiß nur nicht, wie ich es beheben kann/woran es genau scheitert!
-
Also, malloc() kennt nur eine Form des Schiefgehens und die liefert brav ein NULL zurück, wenn was nicht klappt.
Du verläßt Dich drauf, daß malloc() immer klappt (keine Prüfung auf NULL), das ist haarsträubend!
Wenn's dabei mitm Segfault kracht, dann weil die Zuweisung nicht zulässig ist, muß nix mit dem malloc() an und für sich zu tun haben.Also, fang erstmal all diese Fehlerquellen ab und schmeiß' bitte auch alle casts von malloc() raus. Sie sind nicht nur unnütz, sondern haben Seiteneffekte.
Viel Spaß dabei!
-
Das ist keine große Hilfe übrigens, wenn man einfach "ausgelacht" wird. Ist ja nicht so, als ob ich mich nicht bemühen würde! Dass man die mallocs alle überprüfen muss, wusste ich einfach nicht und brauchte ich bisher auch nicht machen.
-
julieann schrieb:
Das ist keine große Hilfe übrigens, wenn man einfach "ausgelacht" wird. Ist ja nicht so, als ob ich mich nicht bemühen würde! Dass man die mallocs alle überprüfen muss, wusste ich einfach nicht und brauchte ich bisher auch nicht machen.
Sehe nichts, wo du ausgelacht wirst. Und falls du das aus dem Smiley ableitest, dann liegst du einfach falsch.
-
Es wird Dir auch nicht helfen, beleidigte Leberwurst zu spielen - gelacht hat hier niemand.
Aber Du hast gleich ein paar Forumsregeln mißachtet und damit kein echtes Bemühen erkennen lassen. Wir haben hier eine FAQ, von der ich Dir erstmal Dynamischer Speicher ans Herz lege. RTFM! oder warum dir keiner helfen will... solltest Du auch mal lesen.
Ein paar C- Referenzen können auch nicht schaden, man.cx ist recht gut, mit kleinen Beispielchen gesegnet ist C++ Reference (C Library).Als sachdienlichen Hinweis wollte ich verstanden wissen, daß wahrscheinlich die linke Seite der Zuweisung ins Speichernirvana zeigt
. Wenn Du aus der Stelle nicht schlau wirst, an der es kracht, war vermutlich vorher schon was nicht OK.
Aber Du kannst nicht erwarten, daß sich jemand die Mühe macht, 600+ Zeilen zu analysieren, da wird es bei allgemeinen Hinweisen bleiben.
-
pointercrash() schrieb:
Aber Du kannst nicht erwarten, daß sich jemand die Mühe macht, 600+ Zeilen zu analysieren, da wird es bei allgemeinen Hinweisen bleiben.
Sicher. Wenn ich Zeit habe, lasse ich aber einen Compiler über sowas laufen. Hier bin ich ausgestiegen bei
main.c:407: Warnung: ISO-C verbietet verschachtelte Funktionen
Da ist irgendwas gar nicht in Ordnung, in Approx() werden Typen deklariert (das darf man, wenn man unbedingt will), aber auch Funktionen (das darf nicht sein). Klär das mal.
Edit: Zeilennummer angepasst
-
Ok, vielen dank schonmal.
ich wollte nicht beleidigt erscheinen. Für eine Anfängerín ist es nur manchmal schwer zu verstehen, was valgrind meint beispielsweise. Ich bemühe mich. Bin bei der Arbeit und habe hier keinen Compiler etc.
OK, zu Hause werde ich natürlich die Funktionen aus Approx rausnehmen (das Problem sind hier wohl die Funktionen der verketteten Liste).
Mir fehlen definitiv frees, die sich auf die mallocs in den Zeilen 495 - 498 beziehen. Kann mir jemand sagen, wie ich diese ind er Funktion Approx richtig setzen muss? Ich hatte in der Uni auch überprüft, ob diese mallocs dort NULL zurückgeben.Tun sie aber nicht. Was kann nun den Speicherzugriffsfehler in den Zeilen 504 - 508 verursachen? Weiß da jemand weiter?
-
julieann schrieb:
Ich hatte in der Uni auch überprüft, ob diese mallocs dort NULL zurückgeben.Tun sie aber nicht. Was kann nun den Speicherzugriffsfehler in den Zeilen 504 - 508 verursachen? Weiß da jemand weiter?
Sagte ich schon, newRSPI hat vermutlich keinen Pointer auf gültigen Speicher, sondern zeigt irgendwohin.
Davon abgesehen mußt Du ALLE malloc() absichern, weil Dein Problem nicht mit dem malloc an dieser Stelle auftritt, sondern mit der Zuweisung an newRSPI.Grab' mal eher in der Richtung, wie Du newRSPI Speicher verschaffst, also wirklich Stück für Stück durchdebuggen.
WANN genau z.B. haut's das Ding lang, bei dem ersten Durchlauf oder später. valgrind kann man recht gut triggern lassen, soweit ich mich erinnere.Wenn Du den Bug mal hast, werden wir schon einen Platz für free finden ...
-
Achte mal darauf einen C-Compiler tz benutzen, ich glaub nämlich daß du das durch einen C++ Compiler jagst.