Zahlendarstellung zu beliebiger Basis
-
Hi,
ich habe versucht einen Algorithmus in C zu implementieren der es mir Ermöglicht eine Zahl a des Dezimalsystems in zu einer beliebigen Basis B darstellen zu lassen.#include <stdio.h> #include <stdlib.h> #include <math.h> void EinfuegenEnde(int *z, int *L, int r) { int* tmp; if((tmp=realloc(z,*L+1))) { z=tmp; *(z+*L-1)= r; } else printf("ERROR REALLOC"); } void BasisN(int a, int B, int* L, int* z) { int q = a / B; int r = a % B; if (q == 0) { *(z+*L-1) = r; } else { EinfuegenEnde(z, L, r); *L = *L + 1; BasisN(q, B, L, z); } } int main() { int *z = malloc(sizeof(int)); int *L = malloc(sizeof(int)); int i; *L = 1; BasisN(1234, 2, L, z); for (i = 0; i < *L; i++) { printf("%i", z[*L-1-i]); } free (z); free (L); return 0; }
der Code wird auch ohne Warnings und Probleme vom Compiler bearbeitet aber leider scheint es immer wieder zu irgendwelchen Speicherproblemen zu kommen die ich bei bestem Willen nicht lösen kann.
Hoffe irgendwer kann mir helfen
-
Das funktioniert anscheinend alles nur zufällig, weil realloc den übergebenen Block wenn möglich nur vergrößert und somit denselben Zeiger nochmal zurückgibt. Wenn realloc einmal neu alloziert und umkopiert geht alles den Bach runter.
Und zwar hast du anscheinend vergessen (ich nehme an dass du das eigentlich weißt), dass in C Funktionsargumente by-value übergeben werden. Wenn du also dein z an EinfuegenEnde übergibst und dort drin änderst (z=tmp), kommt diese Änderung bei z nicht an.
Vielleicht gibt es noch mehr Fehler, ich hab jetzt keine Lust durch diesen konfusen Code durchzusteigen.
-
Sorry, hab den Code vllt nicht ganz ausreichend verdeutlicht.
Zum Code selber:
z soll ein Array auf die Ziffernfolge der Zahl in der neuen Basis sein.
L die Länge dieser Ziffernfolge
a die umzuwandelnde Zahl
B die neue BasisDie Funktion BasisN soll die neuen Ziffern errechnen und die Funktion EinfuegenEnde aufrufen die diese Ziffern in das Array schreibt, bis die Rekursion BasisN beendet.
Nun zu deiner Hilfe, ich übergebe z an EinfuegenEnde und versuche z ja zu vergrößern, dies tue ich per realloc und lasse z auf den von realloc zurückgegebenen Pointer zeigen. Und das wird dann nach Durchführung des Programmes wieder vergessen? Wenn ich das Programm nämlich Debugge scheint dieser Teil schon zu funktionieren.
-
MiED schrieb:
Nun zu deiner Hilfe, ich übergebe z an EinfuegenEnde und versuche z ja zu vergrößern, dies tue ich per realloc und lasse z auf den von realloc zurückgegebenen Pointer zeigen. Und das wird dann nach Durchführung des Programmes wieder vergessen? Wenn ich das Programm nämlich Debugge scheint dieser Teil schon zu funktionieren.
void func(int a) { a = 0; } int main() { int a = 42; func(a); return 0; }
Welchen Wert hat a am Ende der main-Funktion?
-
Ok Fehler gesehen. Hab meinen Code dann nochmal überarbeitet:
#include <stdio.h> #include <stdlib.h> #include <math.h> int * EinfuegenEnde(int *z, int *L, int r) { int* tmp; if((tmp=realloc(z,*L+1))) { z=tmp; *(z+*L-1)= r; return z; } else { printf("ERROR REALLOC"); return 0; } } int * BasisN(int a, int B, int* L, int* z) { int q = a / B; int r = a % B; if (q == 0) { *(z+*L-1) = r; return z; } else { z=EinfuegenEnde(z, L, r); /* ist z=EinfuegenEnde redundant da EinfuegenEnde z zurueckgibt? */ *L = *L + 1; BasisN(q, B, L, z); } return 0; /* irrelevant, da durch rekursion immer der fall q==0 erreicht wird, oder? */ } int main() { int *z = malloc(sizeof(int)); int *L = malloc(sizeof(int)); int i; *L = 1; BasisN(128, 2, L, z); for (i = 0; i < 7; i++) { printf("%i", z[7-1-i]); } free (z); free (L); return 0; }
Die Speicherfehler bleiben leider immernoch.
-
Der Fehler ist ja auch nicht vollständig behoben.
Zu den eingefügten Fragen:
-
/* ist z=EinfuegenEnde redundant da EinfuegenEnde z zurueckgibt? */
Nein, warum? Wegen der Namensgleichheit? Die ist irrelevant (wär ja noch schöner wenn eine aufgerufene Funktion mir meine lokalen Variablen ändern dürfte). -
/* irrelevant, da durch rekursion immer der fall q==0 erreicht wird, oder? */
Nein, das return wird nach Rückkehr aus dem rekursiven Aufruf erreicht. Du solltest auch nicht 0 zurückgeben, sondern den Rückgabewert des rekursiven Aufrufs weiterreichen.
BTW hatte ich ursprünglich eigentlich darauf hinweisen wollen, dass du einen Zeiger auf z übergeben sollst.
Edit: Noch ein Fehler, du müsstest das Argument bei realloc noch mit sizeof(int) multiplizieren.
-
-
Wow, mir ist grade beim debuggen aufgefallen das das Programm relativ weit am Ziel vorbeiprogrammiert ist. Werde erstmal das Programm sinnvoll machen bevor ich weitere Fragen dazu stelle.
EDIT: Alle Fehler gefunden, berichtigt und nu gehts.