Servus, ich komm ums verrecken nicht klar mit den dummen Zeigern. Ich sitz nun schon mehrere Stunden an einer Aufgabe und bekomme sie einfach nicht zum laufen. Ich soll ein Programm schreiben dass 100 unsigned int variablen dynamisch allokiert. anschließend soll ich in die 42. variable den wert 888 eintragen und mit printf ausgeben. Das ganze habe ich so angefangen jedoch weiß ich nicht wie ich nun ins 42. array den wert 888 eintragen soll. irgendwie verwirrt mich das ganze mit den zeigern total. skript und ein buch welches ich habe gehen auf malloc nur sehr kurz ein und helfen mir auch nicht wirklich weiter. kann mir vielleicht jemand von euch kurz helfen? #include "include files.h" struct Test { unsigned int aZahl [100]; } int main (void) { struct Test *sTest; int a; printf("Number of adresses: "); scanf("d", &a); sTest = (struct Test*) malloc(a*sizeof(struct Test)); free (sTest); getch(); }
> Ich soll ein Programm schreiben dass 100 unsigned int variablen > dynamisch allokiert. Und warum definierst Du dann eine Struktur, in der ein Array mit 100 Elementen enthalten ist? Das hat doch mit der Aufgabenstellung nichts zu tun.
Anton schrieb: > Ich soll ein Programm schreiben dass 100 unsigned int variablen > dynamisch allokiert. anschließend soll ich in die 42. variable den wert > 888 eintragen und mit printf ausgeben. irgenwie denkst du zu kompliziert, mach es doch genau der reihenfolge. int* pI = (int*)malloc( 100 * sizeof(int) ); pI[42-1] = 888; --print kannst du ja mal selber versuchen free( pI ); fehlerbehandlung sollte auch noch rein.
Peter schrieb: > irgenwie denkst du zu kompliziert, mach es doch genau der reihenfolge. ich glaubs mittlerweile auch. habs halt nach meinem skript geschrieben und da war es halt so drinn. Peter schrieb: > int* pI = (int*)malloc( 100 * sizeof(int) ); > pI[42-1] = 888; > --print kannst du ja mal selber versuchen > free( pI ); das ist alles? ganz ehrlich darauf wäre ich nie gekommen mit dem dummen skript. was ich aber nicht verstehe ist was mir dass nun bringt. die nächste frage ist nämlich was liefert die funktion malloc für einen rückgabewert zurück? 888 oder versteh ich dass schon wieder falsch?
Anton schrieb: > was liefert die funktion malloc für einen rückgabewert zurück? schau doch mal in die Dokumentation, zur not einfach mal bei google malloc eingeben.
Anton schrieb: > oder gibt er null zurück weil er den speicher wieder freigibt? wie kann malloc speicher freigeben?
Peter schrieb: > int* pI = (int*)malloc( 100 * sizeof(int) ); warum casten, wenn es doch C ist? int* pI = malloc( 100 * sizeof(int) ); wenn es C++ sein soll ausserdem ist es etwas aufbereitet :) int * pi = new int[100], * px = pi + 41; *px = 888; delete [] pi;
Daniel -------- schrieb: > int * pi = new int[100], * px = pi + 41; > *px = 888; > delete [] pi; 1.ich finde das new bei array nicht schön, ich verwende auch bei c++ malloc. 2. zwei anweisungen in einer zeile sind mehr als unschön 3. es geht hier ja um arrays also sollte man auch den array syntax verwenden und nicht irgendwelche zeiger addieren. (Mir ist klar das es gleich ist)
Daniel -------- schrieb: >> int* pI = (int*)malloc( 100 * sizeof(int) ); > > warum casten, wenn es doch C ist? > int* pI = malloc( 100 * sizeof(int) ); Weil das eine Warning gibt! > wenn es C++ sein soll > ausserdem ist es etwas aufbereitet :) > > int * pi = new int[100], * px = pi + 41; > *px = 888; > delete [] pi; Toll der TO versteht noch nicht mal was ein Zeiger eigentlich ist, und du wirfst ihm noch alternative C++ Systax hin. Damit hast du ihm bestimmt geholfen. @Anton: Du brauchst unbedingt ein C-Buch. Das gute alte Kerningham Ritchie "programming in C" ist keine schlechte Wahl. Du musst unbedingt verstehen was ein Zeiger (Pointer) ist, sonst wird das nichts. Bei Bedarf konkrete Fragen stellen.
>#include "include files.h"
Das ist übrigens schon Unfug... (2. include wegnehmen)
Peter schrieb: > 1.ich finde das new bei array nicht schön, ich verwende auch bei c++ > malloc. Das ist, Verzeihung, eher dumm. Ruft malloc den Konstruktor für erzeugte Objekte auf? Na?
Udo Schmitt schrieb: >> warum casten, wenn es doch C ist? >> int* pI = malloc( 100 * sizeof(int) ); > > Weil das eine Warning gibt! nö, wenn du C meinst dann nicht wenn ich mich richtig erinnere kannst du int * pi; double * pd; void * pv; einader zuweisen. Was nicht geht ist struct X {int dummy;}; struct X * px; px = pi; dummerweise geht das dennoch über den Umweg pi = pv; px = pv; naja man muss schon wegen dem aligning aufpassen pv = pi; // geht sogar in C++, da nach void * implizit pi = pv; // geht nur in C ohne Warnung
*(&gast) schrieb: > Das ist übrigens schon Unfug... (2. include wegnehmen) und warum? ich hab ne header datei die heißt "include files.h" und die füge ich in mein hauptprogramm ein.
Anton schrieb: > *(&gast) schrieb: >> Das ist übrigens schon Unfug... (2. include wegnehmen) > > und warum? ich hab ne header datei die heißt "include files.h" und die > füge ich in mein hauptprogramm ein. Na dann... Ist aber ein sehr ungewöhnlicher Name, besonders das Leerzeichen macht mir Kopfweh.
Anton schrieb: > und warum? ich hab ne header datei die heißt "include files.h" und die > füge ich in mein hauptprogramm ein. Das lässt darauf schließen, daß Du in der wiederum alle möglichen anderen Dateien einbindest ... gewöhn Dir das besser wieder ab.
Rufus Τ. Firefly schrieb: > Das lässt darauf schließen, daß Du in der wiederum alle möglichen > anderen Dateien einbindest ... gewöhn Dir das besser wieder ab. mein dozent hat gemeint dass wir es so machen sollen da es wenn es zu viele include files in einer datei gibt es viel zu unübersichtlich wird. naja habs mir ehrlich gesagt auch fast schon gedacht dass ich es wieder anders machen soll. dachte halt wenn er es sagt wird es schon stimmen.
Rufus Τ. Firefly schrieb: > Das ist, Verzeihung, eher dumm. Ruft malloc den Konstruktor für > erzeugte Objekte auf? Na? wozu sollte ich das bei int gebrauchen? Damit es langsamer geht? Wenn ich richtige Objekte verwende nehme ich eh sachen aus der STL.
Anton schrieb: > mein dozent hat gemeint dass wir es so machen sollen da es wenn es zu > viele include files in einer datei gibt es viel zu unübersichtlich wird. Dein Dozent sollte mal reale Programme schreiben, dann würde er nicht so einen Unsinn verzapfen. Aber ok, da kommst du nicht besonders gut raus. Merk dir einfach: So was macht man nicht. Wenn dein Kurs aus ist und du weiter bei C bleibst, gewöhnst du dir das gleich wieder ab. > naja habs mir ehrlich gesagt auch fast schon gedacht dass ich es wieder > anders machen soll. dachte halt wenn er es sagt wird es schon stimmen. Das Problem mit den meisten Dozenten auf der Uni: Sie haben selber nur wenig Ahnung.
Peter schrieb: > Rufus Τ. Firefly schrieb: >> Das ist, Verzeihung, eher dumm. Ruft malloc den Konstruktor für >> erzeugte Objekte auf? Na? > > wozu sollte ich das bei int gebrauchen? Völlig Wurscht. Bei C++ nimmt man kein malloc. Es sei denn man muss mit altem C Code interagieren. > Damit es langsamer geht? Ob das tatsächlich langsamer ist oder nicht, ist ein zu beweisendes. Höchst wahrscheinlich ist es das nicht. Aber ein bunter Mix aus C++ new und C malloc ist ein sicherer Weg ins Desaster. BTW: Wie machst du es denn in Templates? Spezialisierst du die dann auf die Basistypen, damit du malloc nehmen kannst? > Wenn > ich richtige Objekte verwende nehme ich eh sachen aus der STL. Und wenn nichts aus der STL passt?
Karl heinz Buchegger schrieb: > Aber ein bunter Mix aus C++ new und C malloc ist ein sicherer Weg ins > Desaster. damit hatte ich noch nie Probleme > Und wenn nichts aus der STL passt? hatte ich auch noch nie, denn malloc verwende ich wirklich nur bei einfachen Datentypen oder bei puffer für Daten. ich verwende also genauso new wenn es um zeiger auf objekte geht, ich verwende es nur nicht bei arrays.
Peter schrieb: > Daniel -------- schrieb: >> int * pi = new int[100], * px = pi + 41; >> *px = 888; >> delete [] pi; > > 1.ich finde das new bei array nicht schön, ich verwende auch bei c++ > malloc. Was ist daran "nicht schön"? Ich finde
1 | int * pi = new int[100]; |
jedenfalls deutlich schöner, als:
1 | int * pi = static_cast<int*>(malloc(100 * sizeof *pi)); |
Peter schrieb: > Rufus Τ. Firefly schrieb: >> Das ist, Verzeihung, eher dumm. Ruft malloc den Konstruktor für >> erzeugte Objekte auf? Na? > > wozu sollte ich das bei int gebrauchen? Damit es langsamer geht? Wenn > ich richtige Objekte verwende nehme ich eh sachen aus der STL. Und warum bei int nicht?
Rolf Magnus schrieb: > int * pi = static_cast<int*>(malloc(100 * sizeof *pi)); so hat es ja auch niemand geschrieben, wir wissen ja nicht mal ob es C oder C++ sein soll. Meine Version geht sollte bei C und C++ ohne warnungen funktionieren. geht sizeof überhaupt ohne klammern? Geht es überhaupt wenn es in der gleiche zeile steht wie die eigentlich deklaration auf die man sich bezieht? > Und warum bei int nicht? weil ich es nicht schön finde, weil ich altmodisch bin oder sonstetwas - ich mach es halt nicht. (Wenn für jedes int noch der konstruktor aufgerufen wird ist es auch noch langsamer! (was mal zu prüfen währe) )
Peter schrieb: > Rolf Magnus schrieb: > >> int * pi = static_cast<int*>(malloc(100 * sizeof *pi)); > so hat es ja auch niemand geschrieben, so wäre es aber richtig :-) > wir wissen ja nicht mal ob es C > oder C++ sein soll. Ist ganz einfach Wenns C sein soll, lautet es richtig int* pI = malloc( 100 * sizeof(int) ); oder noch besser int* pI = malloc( 100 * sizeof(*pI) ); wenns C++ sein soll, lautet es richtig int* pI = new int[100]; > Meine Version geht sollte bei C und C++ ohne > warnungen funktionieren. Deine Version ist ein Mittelding aus Fisch und Fleisch. Es ist weder richtiges C noch richtiges C++. Syntaktisch ist es zwar korrekt, aber in keiner der beiden Sprachen ist es die 'richtige' Lösung, so wie man es in der jeweiligen Sprache machen würde. Über Feinheiten wie Excpetion Handling in C++ reden wir erst mal gar nicht. Es geht darum, ob dich der Compiler vor Fehlern schützen kann oder nicht. > int* pI = (int*)malloc( 100 * sizeof(int) ); * du hast den Header für malloc vergessen Tja. Dann gibt das nur eine Warnung, wenn überhaupt bei sizeof(int) != sizeof(void*) gibt es allerdings massenhaft Ärger > int* pI = malloc( 100 * sizeof(char) ); * Tja, der Compiler kann dir hier nicht helfen. malloc ist nur ein Funktionsaufruf und kein Schlüsselwort. Zwischen der Allokierungslänge und dem Pointer links von der Zuweisung gibt es keinen Zusammenhang. C und C++ sind schon lange 2 verschiedene Sprachen, die man auch getrennt behandeln sollte. Jeder Cast, der nicht unbedingt notwendig ist, ist ein Cast zuviel. Speziell beim Umcasten von Pointern ist extreme Vorsicht geboten. So einen Cast führt man niemals ohne große Not ein, wenn es eine Alternative gibt. > ich mach es halt nicht. (Wenn für jedes int noch der konstruktor > aufgerufen wird ist es auch noch langsamer! So dämlich ist der COmpiler dann auch wieder nicht. Du kannst deinem C++ Compiler ruhig etwas zutrauen. Die Teile sind besser als du glaubst. Und im Zweifelssfall gibt es ja auch noch die Sprachdefinition, in der explizit festgehalten wird, dass Basistypen uninitialisiert zur Welt kommen (ausser global und static) - ein Zugeständnis an die C Vorfahren von C++
Peter schrieb: >> int * pi = static_cast<int*>(malloc(100 * sizeof *pi)); > so hat es ja auch niemand geschrieben, wir wissen ja nicht mal ob es C > oder C++ sein soll. Meine Version geht sollte bei C und C++ ohne > warnungen funktionieren. Naja, in C++ vermeide ich C-Style-Casts, und ich brauche abgesehen von Headern eigentlich nie Code, der als beides übersetzbar ist. > geht sizeof überhaupt ohne klammern? Kommt drauf an. Bei Typen nein, bei Werten ja:
1 | int main() |
2 | {
|
3 | int i; |
4 | sizeof i; // ok |
5 | sizeof int; // Fehler |
6 | return 0; |
7 | }
|
> Geht es überhaupt wenn es in der gleiche zeile steht wie die eigentlich > deklaration auf die man sich bezieht? Ja. Der Name und Typ von pi sind bekannt, sobald das 'int * pi' fertig ist. Danach, also auch schon bei der Initialisierung, kann man sich darauf beziehen. Syntaktisch ist sogar 'int * pi = pi;' korret, produziert aber natürlich Unsinn. Der Vorteil von 'sizeof *pi' gegenüber 'sizeof(int)' liegt darin, daß man bei einer Änderung des Typs von pi nicht vergessen kann, das sizeof mit anzupassen. Karl heinz Buchegger schrieb: >> ich mach es halt nicht. (Wenn für jedes int noch der konstruktor >> aufgerufen wird ist es auch noch langsamer! > > So dämlich ist der COmpiler dann auch wieder nicht. > Du kannst deinem C++ Compiler ruhig etwas zutrauen. Die Teile sind > besser als du glaubst. Und im Zweifelssfall gibt es ja auch noch die > Sprachdefinition, in der explizit festgehalten wird, dass Basistypen > uninitialisiert zur Welt kommen (ausser global und static) Die Standard-Container machen allerdings eine Initialisierung aller Elemente.
Karl heinz Buchegger schrieb: > Deine Version ist ein Mittelding aus Fisch und Fleisch. Es ist weder > richtiges C noch richtiges C++. das is ja das schöne an C++ mann kann/darf alles von C verwenden > Du kannst deinem C++ Compiler ruhig etwas zutrauen. Die Teile sind > besser als du glaubst das wird immer mal behauptet aber leider stimmt es nur sehr bedingt. Hier war letzen erst eine eine Diskusion int i; if ( a > 1.345 ) { mach was } für den Vergleich werden die float routinen verwendet und das ist nicht gerade sinnvoll.
Rolf Magnus schrieb: >> geht sizeof überhaupt ohne klammern? > > Kommt drauf an. Bei Typen nein, bei Werten ja: Wobei die Klammern allerdings auch nicht stören. Die meisten schreibens daher immer mit Klammern. Wenn ich so darüber nachdenken: Ich kenn eigentlich niemanden, der die Klammern weglässt.
Peter schrieb: > das is ja das schöne an C++ mann kann/darf alles von C verwenden Das trifft nicht zu:
1 | int *p; |
2 | void *v; |
3 | |
4 | p = v; |
ist in C legal, in C++ aber nicht. Welchen Typ aber hat der Rückgabewert von malloc?
Rufus Τ. Firefly schrieb: > Das trifft nicht zu: > int *p; > void *v; > > p = v; > ist in C legal, in C++ aber nicht. Darum kommt bei mir auch ein cast rein p = (int*)v schon passt es wieder, man darf auch bei "alten" C variabeln nur am anfang eines Blockes anlegen - aber darum geht es hier nicht. > Welchen Typ aber hat der Rückgabewert von malloc? void* aus dem grund ja auch der cast.
Peter schrieb: > Karl heinz Buchegger schrieb: >> Deine Version ist ein Mittelding aus Fisch und Fleisch. Es ist weder >> richtiges C noch richtiges C++. > das is ja das schöne an C++ mann kann/darf alles von C verwenden Naja, nicht alles. Aber welchen Vorteil versprichst du dir davon, wenn sich einzelne Zeilen aus deinem C++-Programm auch als C übersetzen ließen, wenn man es denn wollte?
Rolf Magnus schrieb: > aber welchen Vorteil versprichst du dir davon, wenn > sich einzelne Zeilen aus deinem C++-Programm auch als C übersetzen > ließen, wenn man es denn wollte? keine, aber auch kein Nachteil. Es ist einfach gewohnheit.
Peter schrieb: > Darum kommt bei mir auch ein cast rein Dann hast Du nicht verstanden, worum es geht. Du schreibst, daß in C++ alles erlaubt wäre, was in C auch erlaubt ist, machst dann aber in C völlig unnötige (und obendrein fehlerträchtige) Anpassungen in Form von typecasts. Damit führst Du Deine Aussage selbst ad absurdum. >> Welchen Typ aber hat der Rückgabewert von malloc? > void* aus dem grund ja auch der cast.
Peter schrieb: > Rolf Magnus schrieb: >> aber welchen Vorteil versprichst du dir davon, wenn >> sich einzelne Zeilen aus deinem C++-Programm auch als C übersetzen >> ließen, wenn man es denn wollte? > keine, aber auch kein Nachteil. Oh doch! Das ist nämlich dein Trugschluss. Gewisse Dinge in C sind nämlich in C++ aus gutem Grund für illegal erklärt worden. Zur Not kann man das mit einem alten C Cast umgehen, aber das ist nicht der Sinn der Sache. Am besten man trägt den Glauben, dass C ein Subset von C++ sei, schön langsam zu Grabe. Das hat nie gestimmt und in den letzten Jahren entfernen sich die beiden Sprachen immer weiter voneinander, so dass die Kluft immer größer wird. Dieses Subset Gehabe war am Anfang ein notwendiges Übel um den C-Programmierern den Umstieg auf C++ schmackhaft machen zu können. Einige der weniger schönen Dinge in C++ sind auch heute noch darauf zurückzuführen. Heutzutage fährt man aber mit der Sichtweise, dass man es hier mit 2 verschiedenen Sprachen zu tun hat, besser. Programmiert man C, dann aber auch richtig. Programmiert man C++, dann aber auch richtiges C++
Rufus Τ. Firefly schrieb: > machst dann aber in C > völlig unnötige (und obendrein fehlerträchtige) Anpassungen in Form von > typecasts. ja aber in C++ brauche ich ihn und ja manchmal schreibe ich noch reine C Programme. Und mit dieser Version kann ich in beiden Umgebungen gut leben. Es ist nicht falsch und funktioniert, mehr will ich nicht.
Karl heinz Buchegger schrieb: > Programmiert man C, dann aber auch richtig. > Programmiert man C++, dann aber auch richtiges C++ in der Theorie ja, in der Praxis nein. Es gibt genug Gründe auch noch alte DLLs zu verwenden wo man ständig mit cast arbeiten muss. Klar könnte man auch die Header anpassen aber das tun ich mir nicht an.
Peter schrieb: > Es ist nicht falsch und funktioniert, mehr will ich nicht. Das ist soweit auch in Ordnung, nur ist dann so eine Aussage Peter schrieb: > das is ja das schöne an C++ mann kann/darf alles von C verwenden eben absolut unhaltbar.
Peter schrieb: > Karl heinz Buchegger schrieb: >> Programmiert man C, dann aber auch richtig. >> Programmiert man C++, dann aber auch richtiges C++ > > in der Theorie ja, in der Praxis nein. Wie ich leider bestätigen muss, nachdem ich hier ein Projekt übernommen habe. Es gibt leider immer noch viel zu viele Programmierer, die zwar offiziell C++ programmieren in Wirklichkeit aber seit ihren C-Zeiten den Umstieg nicht geschafft haben und auch heute noch C programmieren. Dementsprechend sehen dann auch die Programme aus und dementsprechend fehlerhaft sind sie auch. Wenn dann auch noch ein falsches Verständnis für 'Optimierungen' dazu kommt, dann wirds ganz schlimm. Und so sitze ich hier vor einem Haufen C-Code, der sich zwar C++ schimpft aber bei dem der Programmierer die C Denkweise der Daten-struct und 'jeder darf alles' nicht ablegen konnte (Datenkapselung, die richtige Klasse für die richtige Funktionalität auswählen, Klassen delegieren Aufgaben an andere Klassen, was ist das?) und kann zusehen, wie ich möglichst minimalinvasiv den gröbsten Unsinn so weit hinkriege, dass die Bugs beseitigt werden. Dabei wäre alles mit den richtigen Klassen und einer sauberen Aufgabenteilung unter den Klassen so einfach gewesen .... > Es gibt genug Gründe auch noch > alte DLLs zu verwenden wo man ständig mit cast arbeiten muss. Ich hatte weiter oben Interfacing zu vorhandenen und nicht änderbaren C Schnittstellen explizit ausgenommen.
Anton schrieb: > mein dozent hat gemeint dass wir es so machen sollen da es wenn es zu > viele include files in einer datei gibt es viel zu unübersichtlich wird. > > naja habs mir ehrlich gesagt auch fast schon gedacht dass ich es wieder > anders machen soll. dachte halt wenn er es sagt wird es schon stimmen. also "meine" dozenten haben es (bis auf ein paar ausnahmen, die ich an einer hand (im dezimalsystem!) abzählen kann) gerne gesehen, wenn sich studenten mit den vorgetragenen inhalten kritisch auseinandergesetzt haben und fragen dazu gestellt haben. frag doch einfach mal, wo der unterschied liegt, ob man über 5 zeilen code darüberscrollt, über 50 oder 666. mit einem modernen editor fällt sowas gar nicht auf, mit vi gehts auch recht schnell und emacs ist zwar ein brauchbares betriebssystem, allerdings ohne editor ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.