C: Auf einmal Access Violation, abnormal program termination :(

HentaiD

Mitglied
Hallo Freunde,
die Probleme hören nicht beim debuggen. Ich habe gestern an einer völlig anderen Stelle im Programm versucht einen malloc(); / free(); - Fehler zu beheben und nun wirft mir das Programm hier jetzt eine Access Violation. Offenbar ist doch ein Fehler bei der Speicherallozierung vorgekommen. Ich weiß aber nicht warum und woher der Fehler rührt.
Vorher hat das ganze super funktioniert und jetzt nicht mehr.

Da Valgrind mir aber sowieso dort etwas von lost bytes angezeigt hat, frage ich doch mal lieber nach, weil ich keine Spur habe, wo der Hund begraben sein könnte.

Der Codeschnipsel soll aus einem Array (output_number.words[], ist ein BigInt) Die Bits auslesen und dann dezimal umwandeln, danach das Ergebnis in eine Datei schreiben und auf der Shell / Kommandozeile ausgeben.
Der Fehler passiert aber ganz klar unten bei der Ausgabe beim Zugriff auf die dez_out.

Wäre echt super, wenn ihr mir da weiterhelfen könntet. :)

Viele liebe Grüße, D



Code:
void binToDez(FILE *FDatei){

	int i = 0;
	int j = 0;
	int k = 0;
	int counter = 0;
	int bits = output_number.n * 32;												// Anzahl vorhanderner Binaerbits
	int len = ceil((double)(bits/ DEZTOBINLEN));									// Anzahl der maximalen Arrayplaetze
	char **dez_out;																	// BCD-Code Array mit Dezimalzahlen für jedes Bit

	dez_out = (char **)malloc(bits*sizeof(char *));
   	for(i=0;i<bits;i++){
      dez_out[i] = (char *)malloc(len*sizeof(char));
   	}

	for(j=0; j<output_number.n; j++){												// Jedes Outputwort wird analysiert
		for(i=31; i>=0; i--){
			if( (1 << i) & output_number.words[output_number.n-1-j] )				// Jedes Bit wird analysiert
			{
  				dez_out[counter][len-1] = 1;										// Wenn Bit gesetzt: Fuelle letzten Index mit 1
			}
			else{
   				dez_out[counter][len-1] = 0;										// Wenn kein Bit gesetzt: Fuelle letzen Index mit 0
			}
			counter++;
		}
	}


	for(i=0; i<bits; i++){
		//fprintf(FDatei, "%d", dez_out[i][len-1]);									// BINAERE AUSGABE

		for(j=0; j<len-1; j++){
			dez_out[i][j] = 0;														// Indizes mit 0 initialisieren
		}
	}

	for(i=0; i<bits; i++){
		if(dez_out[i][len-1] == 1){													// Wenn ein Bit im letzten Index gefunden wurde,
			for(j=0; j<bits-i-1; j++){
				for(k=0; k<len; k++){
					dez_out[i][k] = 2 * dez_out[i][k];								// wird hier so oft die Zahl mit 2 multipliziert, wie ihre Wertigkeit ist (1*2^(bits-i-1))
					if(dez_out[i][k] >9){
						dez_out[i][k] -= 10;
						dez_out[i][k-1] += 1;										// kann keinen "Overflow" geben, weil 9en vorher mit 2 multipliziert wurden -> 8
					}
				}
			}
		}
	}


	for(i=bits-2; i>=0; i--){														// Schleife faengt bei zweitniederwertigstem Bit an zu addieren, bis zum letzten (Outputwert)
		if(dez_out[i][len-1] != 0){													// Wenn das letzte Bit nicht null ist
			for(j=0; j<len; j++){
				dez_out[bits-1][j] += dez_out[i][j];
				if(dez_out[bits-1][j] > 9){											// Wenn "overflowt" wurde:
					dez_out[bits-1][j] -= 10;										// 10 abziehen und 1 in den naestmoeglichen Index stecken,
					for(k=j-1; k>=0; k--){
						if(dez_out[bits-1][k] == 9){								// d.h. 9en zu 0 en machen
							dez_out[bits-1][k] = 0;
						}
						else{
							dez_out[bits-1][k]++;									// und bei kleineren Ziffern eine 1 addieren
							break;													// und die Schleife nach Addition des Carry fruehzeitig beenden
						}
					}
				}
			}
		}
	}

	for(i=0; i<len; i++){
		if(i==0){																	// fuehrende Nullen abfangen
			counter = 0;
			for(j=0; j<len; j++){
				if(dez_out[bits-1][j] == 0){
					counter ++;
					if(j == len-1){
						if(counter < 2){
							counter = 2;
						}
						i = counter-2;
						break;
					}
				}
				else{
					i = counter;
					break;
				}
			}
		}

		fprintf(FDatei, "%d", dez_out[bits-1][i]);									// Ausgabe der Dezimalzahl in Ausgabedatei
		printf("%d", dez_out[bits-1][i]);

	}

	free(dez_out);
 
Es ist die for-Schleife in Zeile 73. Die bricht irgendwann bei der Ausgabe ab (94). Der Fehler liegt offenbar aber woanders.

Bei einer Addition von
7971247101245146884800154
und
78901410000007848917314127915791571054545439
gibt er bis hierhin aus: 7971247101245146884800154 (falsche Werte) und bricht dann ab.

Valgrind stört mit folgendem Fehler:

==17622== Invalid read of size 1
==17622== at 0x400AE6: dec2binDiv (1283810484.c:60)
==17622== by 0x400E0D: dec2bin (1283810484.c:132)
==17622== by 0x402C81: main (1283810484.c:805)
==17622== Address 0x5423767 is 1 bytes before a block of size 25 alloc'd
==17622== at 0x4C278AE: malloc (vg_replace_malloc.c:207)
==17622== by 0x400CD4: dec2bin (1283810484.c:99)
==17622== by 0x402C81: main (1283810484.c:805)
==17622==
==17622== Invalid read of size 1
==17622== at 0x400AE6: dec2binDiv (1283810484.c:60)
==17622== by 0x400F9F: dec2bin (1283810484.c:168)
==17622== by 0x402CC9: main (1283810484.c:812)
==17622== Address 0x5423847 is 1 bytes before a block of size 44 alloc'd
==17622== at 0x4C278AE: malloc (vg_replace_malloc.c:207)
==17622== by 0x400CD4: dec2bin (1283810484.c:99)
==17622== by 0x402CC9: main (1283810484.c:812)
==17622==
==17622== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 8 from 1)
==17622== malloc/free: in use at exit: 7,840 bytes in 160 blocks.
==17622== malloc/free: 171 allocs, 11 frees, 11,018 bytes allocated.
==17622== For counts of detected errors, rerun with: -v
==17622== searching for pointers to 160 not-freed blocks.
==17622== checked 73,696 bytes.
==17622==
==17622==
==17622== 7,840 bytes in 160 blocks are definitely lost in loss record 1 of 1
==17622== at 0x4C278AE: malloc (vg_replace_malloc.c:207)
==17622== by 0x402353: binToDez (1283810484.c:640)
==17622== by 0x402A9C: Ausgabe (1283810484.c:755)
==17622== by 0x402D70: main (1283810484.c:834)
==17622==
==17622== LEAK SUMMARY:
==17622== definitely lost: 7,840 bytes in 160 blocks.
==17622== possibly lost: 0 bytes in 0 blocks.
==17622== still reachable: 0 bytes in 0 blocks.
==17622== suppressed: 0 bytes in 0 blocks.
 
Es ist die for-Schleife in Zeile 73. Die bricht irgendwann bei der Ausgabe ab (94). Der Fehler liegt offenbar aber woanders.
Wenn es genau an der Stelle abstürzt, dann liegt der Fehler in erster Linie genau an der Stelle.

Benutze den Debugger. Wie sind die Werte der Variablen bits und i in Zeile 94 beim Absturz?

Valgrind stört mit folgendem Fehler:
Ich sehe nirgendwo eine Stelle wo du die Arrays dez_out[0] bis dez_out[bits-1] freigibst...

Gruß
 
Stimmt! Tatsache, sowas Doofes.

Code:
free(dez_out);
free(*dez_out);

So müsste es aussehen, denke ich.
Ja mein guter Debugger... ich weiß nicht was damit nicht stimmt, aber er selbst wirft lustigerweise eine Access Violation und funktioniert anscheinend nicht. Aber danke schon einmal für den Tipp mit free und jetzt werde ich mich mal auf die Suche nach einem ordentlichen Debugger machen. :(
 
Code:
free(dez_out);
free(*dez_out);

So müsste es aussehen, denke ich.
Auf keinen Fall. Erstens gibst du die Speicherbereiche in der falschen Reihenfolge frei. Und zweitens werden die Bereiche dez_out[1] bis dez_out[bits-1] nicht freigegeben. Du musst eine Schleife verwenden wie bei malloc:

C:
for(i=0;i<bits;i++){
    free(dez_out[i]);
}
free(dez_out);

Grüße,
Matthias
 
Zurück