Zakum Geschrieben 27. April 2010 Geschrieben 27. April 2010 Ich sitze seit einer Weile an einem Problem fest, die Lösung ist vermutlich trivial, aber mittlerweile sehe ich das IKEA vor lauter Möbeln nicht, vlt. ist ja jemand so nett, mir die Augen zu öffnen. Folgendes Code-Schnipsel zum Testen meiner Funktion void* alloc(): ... int main(){ char* adr1=(char*)alloc(); *adr1="E"; // <-- Warnung int* adr2=(int*)alloc); *adr2="2"; // <-- Warnung float* adr3=(float*)alloc(); *adr3=3.5; printf("%c %d %f\n",*adr1,*adr2,*adr3); return 0; } Der Compiler warnt an zwei Stellen vor "Zuweisung erzeugt Ganzzahl von Zeiger ohne Typkonvertierung." Entsprechend sieht auch die Ausgabe aus: ` 134514018 3.500000 Alloc ist eine eigene Speicherverwaltung, und gibt mir die Startadresse eines reservierten Speicherblocks zurück. Im Test versuche ich nun, an die jeweils entsprechenden Adressen zuerst einen Charackter, dann einen Integer und am Ende eine Float zu speichern, und testweise aus zu geben. Da alloc einen Zeiger auf void zurück gibt, caste ich das ganze zuerst auf Zeiger in den entsprechenden Typ, und dereferenziere bei der Zuweisung des Wertes. Warum funktioniert dieser Weg bei int und char nicht? Und warum klappt es dafür mit einem float? Habe ich das was mit den Typen vermengt? Vielen Dank schon jetzt für eure Hilfe! -Zakum Zitieren
Bubble Geschrieben 28. April 2010 Geschrieben 28. April 2010 Warum funktioniert dieser Weg bei int und char nicht? Und warum klappt es dafür mit einem float? Weil in den ersten beiden nicht funktionierenden Fällen versucht wird, die Speicheradresse eines C-Strings zuzuweisen, im zweiten funktionierenden Fall im Gegensatz dazu eine konstante Zahl. Zitieren
Klotzkopp Geschrieben 28. April 2010 Geschrieben 28. April 2010 Das Problem hat gar nichts mit deiner alloc-Funktion zu tun. Die Werte, die du deinen dereferenzierten Zeigern zuweist, passen einfach vom Typ her nicht. *adr1="E"; // <-- Warnung "E" ist char*, nicht char. Nimm 'E' *adr2="2"; // <-- Warnung "2" ist char*, nicht int. Nimm 2 Da alloc einen Zeiger auf void zurück gibt, caste ich das ganze zuerst auf Zeiger in den entsprechenden TypDer Cast ist unnötig. In C ist ein void-Zeiger implizit in jeden anderen Zeigertyp konvertierbar. Der Cast kann unter bestimmten Bedingungen sogar schädlich sein, also lass ihn besser weg. Zitieren
Zakum Geschrieben 28. April 2010 Autor Geschrieben 28. April 2010 Ohh... Ersteres war mir nicht bewusst! Oo Irgend wann verliert man den Überblick, welches Hochkomma in welcher Sprache was bedeutet. ^^ Nehme an, das "..." kennzeichnet einen Stringliteral, und deswegen der char*? Zweiteres... Danke. Drittens hab ich erfolgreich verdrängt gehabt. Könntest du in einer freien Minute kurz anreißen, was der explizite cast an Schaden anrichten kann? Nur so, aus purer Neugier. Ansonsten mal wieder ein großes Dankeschön, ich weiß gar nicht mehr, das wievielte Jahr in Folge du mir schon bei meinen Wehwehchen zur Seite stehst. Zitieren
Klotzkopp Geschrieben 29. April 2010 Geschrieben 29. April 2010 Könntest du in einer freien Minute kurz anreißen, was der explizite cast an Schaden anrichten kann? Im alten C-Standard von 1989 kann man Funktionen verwenden, die vorher nicht deklariert wurden. Der Compiler geht in diesem Fall davon aus, dass die Funktion einen int zurückgibt. Wenn also jemand die alloc-Funktion verwendet, ohne vorher einen Prototypen angegeben zu haben (z.B. weil er vergessen hat, den Header einzubinden), und dabei auf einer Plattform arbeitet, auf der int und void-Zeiger nicht gleich groß sind, kann es sein, dass er sich den Stack zerschießt. Ohne den Cast kommt es dann zumindest zu einer Warnung, z.B. von Visual C++: warning C4047: 'initializing' : 'char *' differs in levels of indirection from 'int' Mit dem Cast wird genau diese Warnung aber unterdrückt. Der Code compiliert dann ohne Probleme, und fliegt dir dann zur Laufzeit um die Ohren, wenn du Glück hast. Wenn du Pech hast, passieren irgendwelche komischen Dinge an ganz anderen Stellen im Code. Zitieren
Zakum Geschrieben 1. Mai 2010 Autor Geschrieben 1. Mai 2010 Vertrackte Sache, das! Gut zu wissen, dankeschön. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.