Ich möchte nochmal etwas zu realloc klarstellen, weil ich dazu gesagt habe, dass ich nicht weiß, warum man nochmals den Zeiger als Parameter übergeben muss. Es macht sehr wohl Sinn, weil realloc ja sonst nicht weiß, welchen Speicherblock er vergrößern soll - und anschließend muss er ja eine neue Adresse zurückgeben. Warum das so ist? Das ist sehr kompliziert, weil hinter Malloc und Co. eine verkettete Liste und die Systemaufrufe sbrk() und brk() stecken. Es ist nur wichtig, dass ihr versteht, dass die alte Adresse als Parameter übergeben werden muss und die neue Adresse der Rückgabewert von realloc ist.
Hallo, erstmal danke für die viele Arbeit und die gute Erklärung. Eine Sache, die ich nie verstanden habe: bei @3:50 sprichst du von einer Adresse, die dann einfach mit 'x' dargestellt wird. Ist die Adresse nicht ein '&x'? Oder ist es dasselbe? Und warum ein pointer bei malloc, aber bei x == NULL nicht mehr? Also mal ist der Stern da, mal nicht - was hat das zu bedeuten?
Alles klar! Ich versuche es mal so zu erklären: So erstellt man eine normale Variable: int a = 1; So erstellt man eine pointer Variable: int *b = a; Wenn du die Zahl der normalen Variable haben willst: printf("%d", a); Wenn du die Adresse der normalen Variable haben willst: printf("%p", &a); Wenn du die Zahl der Pointer-Variable haben willst: printf("%d", *b); Wenn du die Adresse, auf die die Pointer-Variable zeigt, haben willst: printf("%p", b); Wenn du die Adresse der Pointer-Variable selbst haben willst: printf("%p", &b);
I have a question: Initialized as a pointer means, you only need to use the dereference operator if you need to interact with the value inside the memory address it is pointing to. Since you are not using this operator for x to check if it's pointing at NULL means you are in fact checking for the POINTER if it points at NULL, not the value inside the memory address. Am I correct? I'm starting to see a pattern. EDIT: Ich weiß nicht warum ich es in Englisch geschrieben haben.
Ja, das hast du richtig verstanden! Mit NULL ist sozusagen eine Adresse gemeint, also die Adresse 0. Nur wenn du den Wert vom Pointer brauchst, also dass was unter dieser Adresse gespeichert ist, musst du dereferenzieren.
ich wollte mich kurz melden und danke sagen, ich studiere Maschienenbau an der TU Wien und habe dank deiner Playlist 2 in der Klausur geschrieben. Danke vielmals
du machst so tolle videos. Ist für mich eine gute vorbereitung für den schulanfang. aber das einzige was ich nicht verstehe ist: Was bedeutet jetzt genau "wenn der speicherbereich auf null zeigt"?
Vielen Dank, es freut mich sehr, dass Dir meine Videos gefallen! Auf NULL zeigen heißt: Ich lasse einen Pointer nicht auf eine bestimmte Adresse zeigen, sodass er auf nichts zeigt. Man markiert den Pointer somit als nicht existent. Damit kann man dann überprüfen, ob der Zeiger auf eine konkrete Adresse zeigt oder eben auf nichts zeigt. Im Fall der dynamischen Speicherverwaltung überprüfe ich damit, ob malloc/realloc etc. einen Speicherblock in der passenden Größe gefunden haben. Konnten sie keinen Speicherblock am Heap reservieren, der eine passende Größe hat, dann wird NULL zurückgegeben. Konnten sie einen Speicherblock reservieren, der eine passende Größe hat, dann wird die Anfangsadresse des Speicherblocks von malloc/realloc etc. zurückgegeben, sodass man diesen Speicherblock mit Daten beschreiben kann.
Super Video! Hast du ein Video wo du zeigst wie man die Eingabe eines String dynamisch reservierst? So dass genau die Größe des Char Array reserviert wird wie benötigt? Danke
Sehr gute Frage! Wenn du das Programm so schreiben würdest, würde es mit x + 1 funktionieren: int main() { int *vector = malloc(sizeof(int)); // Bitte an dieser Stelle den Zeiger auf NULL überprüfen for (int x = 0; x < 20; x++) { vector = realloc(vector, sizeof(int) * (x + 1)); // An den Anfang der Schleife gesetzt vector[x] = 100; // Erst nachher einen Wert in den neuen Speicherbereich geschrieben printf("%d ", vector[x]); } } Der Grund, warum das funktioniert ist, weil du einen Zeiger vor der Schleife deklarierst und diesem einen Speicherblock zuweist. In der Schleife wird im ersten Durchlauf dann (unnötigerweise) der Speicherbereich nochmals auf die gleiche Größe "verändert". Zuvor hatte der Speicherbereich die Größe eines Integers und beim ersten Schleifendurchlauf hat er auch die Größe eines Integers. Ich habe das Programm mit x + 2 geschrieben, damit ich zuerst den Wert in den reservierten Speicherbereich schreibe und danach (auch beim ersten Schleifendurchlauf) den Speicherbereich tatsächlich um einen Interger vergrößere. Bitte entscheide dich für eine Variante, die für dich leichter zu verstehen ist, wenn du programmierst, ich weiß, ich habe das sehr kompliziert gemacht. Sorry!
super, vielen dank für das gute erklären! wie ist es denn, wenn man eine externe datei hat, die angibt, wie viel speicher man braucht? wie schreibe ich das mit realloc?
Am besten du liest blockweise ein. Reserviere Speicher für einen Block von z. B. 50 Zeichen und wenn das Ende der Datei (EOF) noch nicht erreicht ist, reservierst du wieder Speicher für 50 Zeichen zusätzlich zu diesem Speicherbereich.
Hallo Jan! Vielen Dank für das tolle Video! Ich hab eine Frage, eig. eher zu Pointern. Du reservierst mit malloc / calloc ja immer Speicher, dessen Adresse im Pointer x gespeichert ist. Beim Beispiel mit realloc verwendest du den Pointer und dereferenzierst ihn nicht. Was macht das für nen Unterschied, kann ich auch bei malloc z.B. x = malloc(sizeof(float)) .. machen?
Eine Dereferenzierung nehme ich schon vor, sonst könnte ich keine Elemente in mein dynamisches Array speichen. Nur einer Variable (die kein Pointer ist) ein Malloc zuzuweisen, würde nicht funktionieren. Wir benötigen einen Zeiger, der auf den Anfang des Speicherblocks zeigt. Eine normale Variable (die kein Pointer ist), kann nur auf den Speicher im Speicherblock zugreifen. Ich hoffe ich habe deine Frage richtig verstanden - ansonsten gib Bescheid!
Wie kann ich den einen zweiten Zeiger programmieren der auf meinen alokierten Speicher zeigt? Deine Videos sind echt klasse und passen zu meinem Script
Hier ist die Aufgabe. Muss der zweite Zeiger dann auf den ersten Zeigen? Schreiben Sie ein Programm, welches dynamisch Speicher für 100 Zahlenwerte vom Datentyp int allokiert. Verwenden Sie einen zweiten Zeiger, der ebenfalls auf den Beginn des allokierten Speichers zeigt. Diesen zweiten Zeiger verwenden Sie, um Werte in das Array zu schreiben (von 100 bis 1). Gehen Sie dabei wie folgt vor: Zuweisen, Inkrementieren, Zuweisen, Inkrementieren... Geben Sie danach den gesamten Inhalt des Arrays auf den Bildschirm aus. Sortieren Sie nun dieses Array mit BubbleSort und drucken Sie danach den gesamten Inhalt des allokierten Speichers wieder auf dem Bildschirm aus. Wie kann man die Laufzeit von BubbleSort verbessern? (Hinweis: Array sei schon vorsortiert)
@@Tim28259 Da habe ich etwas durcheinander gebracht: Video 20 handelt vom arithmetischen Überlauf, dauert aber fast eine Stunde, das möchte ich gerne neu machen; Video 25 handelt von Doppelt Verketteten Listen; in Video 17 geht es um strlen und strcmp (dauert auch sehr lange, das würde ich gerne neu machen). Sorry für das Durcheinander!
Ich habe nie verstanden wie ich die Befehle finde oder die Befehle mich. Angenommen ich will alle A s rot darstellen. Wie finde ich die Farbe? Elche Datei muß ich includen? Das habe ich nie verstanden und das konnte nie ein Erklärbär erklären. Wenn man das weiß kennt man die Hilfe zur Selbsthilfe. Ich will doch irgendwas testen um Spaß zu haben. Ich will alle R suchen in einem Wort. Wie würde ich den Befehl suchen finden? Woher weiß ich ob es den Befehl gibt? Wieviel Befehle gibts in C? /500/ oder /3.000/? Woher weiß man das? Welche sollte man am Anfang kennen? Solche einfachen fragen hat ein Erklärbär nie erklärt. Und was ist besser? Eine IDE zu nutzen oder ein Compiler mit der Datei? Wie testet man Programme? Baut man da extra Programm-Dateien? Oder baut man sie im Programm mit ein? So einfache Dinge erklärt ein Erklärbär nie.
der datentyp ,, int " vor dem ,,*" bezieht sich nicht auf dem pointer ,,x" sondern nur auf dem ,, *". Datentyp eines jeden pointers ist ,,unsigned int". * bedeutet nichts anderes als ,,wert in der adresse" . Und *x bedeutet dass der zeiger auf den wert in der von zeiger gespeicherten adresse zeigt.
Na, es sind 3 Jahre her aber hier kommt die triviale Antwort auf deine Frage wieso man bei realloc() den namen des Pointers mitgeben muss: woher soll denn realloc() wissen, zu welchem deiner dutzenden Pointer im Programm es Speicher neuen zuweisen soll? 😅😂
Ich habe vor 2 Jahren bereits eine Antwort nachgereicht (siehe angepinnter Post im Kommentarbereich), aber trotzdem Danke! :) Ich wusste das damals noch nicht, habe es aber dann ergänzt.
Warum manche "freen" sagen ist einfach, manche glauben halt anständig Deutsch zu sprechen und Informatiker zu sein gehe nicht. Finde deine klare Terminologie viel besser danke.
Ich möchte nochmal etwas zu realloc klarstellen, weil ich dazu gesagt habe, dass ich nicht weiß, warum man nochmals den Zeiger als Parameter übergeben muss. Es macht sehr wohl Sinn, weil realloc ja sonst nicht weiß, welchen Speicherblock er vergrößern soll - und anschließend muss er ja eine neue Adresse zurückgeben. Warum das so ist? Das ist sehr kompliziert, weil hinter Malloc und Co. eine verkettete Liste und die Systemaufrufe sbrk() und brk() stecken. Es ist nur wichtig, dass ihr versteht, dass die alte Adresse als Parameter übergeben werden muss und die neue Adresse der Rückgabewert von realloc ist.
Sehr gut aufbereitet, man kann mit minimalem Vorwissen in das Video einsteigen und bekommt alles von der "Picke" an erklärt.
Unglaublich gut und sauber erklärt. Respekt
Einfach nur stark was du hier leistest, Respekt und vielen Dank
vielen Dank für deine Mühe!!! Dies bräuchte ich wieder mal und deine Videos sind daher sehr sehr hilfreich :-). Dir alles Gute!
Super erklärt!! Meine Hochachtung!
Danke, sehr gutes und hilfreiches Video. Noch dazu habe Ich kein Video gefunden, dass das Thema so gut behandelt.
Vielen Dank! Genau so ein Video hätte ich dringend gebraucht, ich verstehe das total.
Du rettest mich vor den Klausuren danke!
Hallo Jan, vielen-vielen Dank, ich habe endlich verstanden wie Dynamische Speicherverwaltung funktioniert! :)
Wow sehr gut erklärt und hast eine sehr angenehme Stimme fürs lehren. Vielen Dank!
Das freut mich sehr! Vielen Dank für dein Feedback! :)
Ein dickes LIKE! Super erklärt, das ich es sogar verstanden habe. Danke sehr für dieses Video.
Du bist echt der Beste! Hab vielen Dank!
Vielen lieben Dank!
Deine Videos sind Ehre.
Vielen Dank! :)
herzlichen dank. das video ist sehr hilfreich. thx
Hallo, erstmal danke für die viele Arbeit und die gute Erklärung. Eine Sache, die ich nie verstanden habe: bei @3:50 sprichst du von einer Adresse, die dann einfach mit 'x' dargestellt wird. Ist die Adresse nicht ein '&x'? Oder ist es dasselbe? Und warum ein pointer bei malloc, aber bei x == NULL nicht mehr? Also mal ist der Stern da, mal nicht - was hat das zu bedeuten?
Alles klar! Ich versuche es mal so zu erklären:
So erstellt man eine normale Variable:
int a = 1;
So erstellt man eine pointer Variable:
int *b = a;
Wenn du die Zahl der normalen Variable haben willst:
printf("%d", a);
Wenn du die Adresse der normalen Variable haben willst:
printf("%p", &a);
Wenn du die Zahl der Pointer-Variable haben willst:
printf("%d", *b);
Wenn du die Adresse, auf die die Pointer-Variable zeigt, haben willst:
printf("%p", b);
Wenn du die Adresse der Pointer-Variable selbst haben willst:
printf("%p", &b);
I have a question: Initialized as a pointer means, you only need to use the dereference operator if you need to interact with the value inside the memory address it is pointing to.
Since you are not using this operator for x to check if it's pointing at NULL means you are in fact checking for the POINTER if it points at NULL, not the value inside the memory address. Am I correct?
I'm starting to see a pattern.
EDIT: Ich weiß nicht warum ich es in Englisch geschrieben haben.
Ja, das hast du richtig verstanden! Mit NULL ist sozusagen eine Adresse gemeint, also die Adresse 0. Nur wenn du den Wert vom Pointer brauchst, also dass was unter dieser Adresse gespeichert ist, musst du dereferenzieren.
Beste Erklärung Dankeee
Super erklärt, vielen Dank !!!
Super verständlich erklärt!
Freut mich, danke!
richtig gut verständlich, thanks alot
Sehr gute erklärungen!! danke!
Vielen Dank! Das freut mich sehr! :)
ich wollte mich kurz melden und danke sagen, ich studiere Maschienenbau an der TU Wien und habe dank deiner Playlist 2 in der Klausur geschrieben. Danke vielmals
Das freut mich sehr!
Ich wünsche Dir viel Erfolg im Studium!
Du bist der beste, vielen Dank
du machst so tolle videos. Ist für mich eine gute vorbereitung für den schulanfang.
aber das einzige was ich nicht verstehe ist:
Was bedeutet jetzt genau "wenn der speicherbereich auf null zeigt"?
Vielen Dank, es freut mich sehr, dass Dir meine Videos gefallen!
Auf NULL zeigen heißt: Ich lasse einen Pointer nicht auf eine bestimmte Adresse zeigen, sodass er auf nichts zeigt. Man markiert den Pointer somit als nicht existent. Damit kann man dann überprüfen, ob der Zeiger auf eine konkrete Adresse zeigt oder eben auf nichts zeigt.
Im Fall der dynamischen Speicherverwaltung überprüfe ich damit, ob malloc/realloc etc. einen Speicherblock in der passenden Größe gefunden haben. Konnten sie keinen Speicherblock am Heap reservieren, der eine passende Größe hat, dann wird NULL zurückgegeben. Konnten sie einen Speicherblock reservieren, der eine passende Größe hat, dann wird die Anfangsadresse des Speicherblocks von malloc/realloc etc. zurückgegeben, sodass man diesen Speicherblock mit Daten beschreiben kann.
@@INTOITYT Danke sehr, du hilfst mir sehr im unterricht weiterzukommen. von dir habe ich sehr vieles gelernt❤
PS: Entschuldigung für die späte Antwort
danke! sehr schön erklärt!
Super Video! Hast du ein Video wo du zeigst wie man die Eingabe eines String dynamisch reservierst? So dass genau die Größe des Char Array reserviert wird wie benötigt? Danke
Nein, leider nicht, aber vielleicht hilft dir dieser Code als Ausgangspunkt weiter ;)
#include
#include
#include
int main()
{
char* string = (char*) malloc(sizeof(char) * 6);
strcpy(string, "Hallo");
printf("%s
", string);
string = (char*) realloc(string, sizeof(char) * 11);
strcpy(string, "HalloHallo");
printf("%s
", string);
return 0;
}
Wieso wird bei der Zeile : "" vector = realloc(vector, sizeof(int) * (x+2)); "" +2 gerechnet und nicht +1. Bzw. wieso funktioniert das nicht?
Sehr gute Frage!
Wenn du das Programm so schreiben würdest, würde es mit x + 1 funktionieren:
int main()
{
int *vector = malloc(sizeof(int));
// Bitte an dieser Stelle den Zeiger auf NULL überprüfen
for (int x = 0; x < 20; x++)
{
vector = realloc(vector, sizeof(int) * (x + 1)); // An den Anfang der Schleife gesetzt
vector[x] = 100; // Erst nachher einen Wert in den neuen Speicherbereich geschrieben
printf("%d
", vector[x]);
}
}
Der Grund, warum das funktioniert ist, weil du einen Zeiger vor der Schleife deklarierst und diesem einen Speicherblock zuweist. In der Schleife wird im ersten Durchlauf dann (unnötigerweise) der Speicherbereich nochmals auf die gleiche Größe "verändert". Zuvor hatte der Speicherbereich die Größe eines Integers und beim ersten Schleifendurchlauf hat er auch die Größe eines Integers.
Ich habe das Programm mit x + 2 geschrieben, damit ich zuerst den Wert in den reservierten Speicherbereich schreibe und danach (auch beim ersten Schleifendurchlauf) den Speicherbereich tatsächlich um einen Interger vergrößere. Bitte entscheide dich für eine Variante, die für dich leichter zu verstehen ist, wenn du programmierst, ich weiß, ich habe das sehr kompliziert gemacht. Sorry!
@@INTOITYT Ich habe es jetzt verstanden, danke vielmals für die schnelle und kompetente Antwort!🙂
super, vielen dank für das gute erklären! wie ist es denn, wenn man eine externe datei hat, die angibt, wie viel speicher man braucht? wie schreibe ich das mit realloc?
Am besten du liest blockweise ein. Reserviere Speicher für einen Block von z. B. 50 Zeichen und wenn das Ende der Datei (EOF) noch nicht erreicht ist, reservierst du wieder Speicher für 50 Zeichen zusätzlich zu diesem Speicherbereich.
#include
#include
void main() {
int *vector = malloc (sizeof (int) ) ;
if (vector == NULL)
return 1;
for (int x = 0; x < 20; x++)
{
vector [x] = 100;
printf("%d
", vector [x]);
vector = realloc(vector, sizeof(int) * (x+2));
if (vector == NULL)
{
printf("Kein Speicher Vorhanden");
return 1;
}
}
}
Da fehlt der free(vector); Befehl ;)
Hallo Jan! Vielen Dank für das tolle Video!
Ich hab eine Frage, eig. eher zu Pointern. Du reservierst mit malloc / calloc ja immer Speicher, dessen Adresse im Pointer x gespeichert ist. Beim Beispiel mit realloc verwendest du den Pointer und dereferenzierst ihn nicht. Was macht das für nen Unterschied, kann ich auch bei malloc z.B. x = malloc(sizeof(float)) .. machen?
Eine Dereferenzierung nehme ich schon vor, sonst könnte ich keine Elemente in mein dynamisches Array speichen.
Nur einer Variable (die kein Pointer ist) ein Malloc zuzuweisen, würde nicht funktionieren. Wir benötigen einen Zeiger, der auf den Anfang des Speicherblocks zeigt. Eine normale Variable (die kein Pointer ist), kann nur auf den Speicher im Speicherblock zugreifen.
Ich hoffe ich habe deine Frage richtig verstanden - ansonsten gib Bescheid!
100 Daumen nach👍Top Video!!! 👍
nice danke!
Wie kann ich den einen zweiten Zeiger programmieren der auf meinen alokierten Speicher zeigt? Deine Videos sind echt klasse und passen zu meinem Script
Hallo! Du meinst, dass zwei Zeiger auf einen Bereich zeigen?
@@INTOITYT Genau!
Hier ist die Aufgabe. Muss der zweite Zeiger dann auf den ersten Zeigen?
Schreiben Sie ein Programm, welches dynamisch Speicher für 100 Zahlenwerte vom Datentyp int allokiert. Verwenden Sie einen zweiten Zeiger, der ebenfalls auf den Beginn des allokierten Speichers zeigt. Diesen zweiten Zeiger verwenden Sie, um Werte in das Array zu schreiben (von 100 bis 1). Gehen Sie dabei wie folgt vor: Zuweisen, Inkrementieren, Zuweisen, Inkrementieren... Geben Sie danach den gesamten Inhalt des Arrays auf den Bildschirm aus. Sortieren Sie nun dieses Array mit BubbleSort und drucken Sie danach den gesamten Inhalt des allokierten Speichers wieder auf dem Bildschirm aus. Wie kann man die Laufzeit von BubbleSort verbessern? (Hinweis: Array sei schon vorsortiert)
Warum ist Video Nr.20 nicht zu sehen?^^
Video 20 behandelt die Doppelt Verkettete Liste, aber leider hatte ich keine Zeit das Video zu machen, weil es etwas aufwendig ist.
@@INTOITYT Achso schade, hoffe du schaffst es noch bevor ich meine Klausur in diesem Semester schreibe
@@Tim28259 Wow danke! Ich weiß es nicht, ob ich die Zeit finde, aber ich versuche es! :)
@@INTOITYT Was sind denn 25 & 17 für Themen?
@@Tim28259 Da habe ich etwas durcheinander gebracht: Video 20 handelt vom arithmetischen Überlauf, dauert aber fast eine Stunde, das möchte ich gerne neu machen; Video 25 handelt von Doppelt Verketteten Listen; in Video 17 geht es um strlen und strcmp (dauert auch sehr lange, das würde ich gerne neu machen). Sorry für das Durcheinander!
Ich habe nie verstanden wie ich die Befehle finde oder die Befehle mich. Angenommen ich will alle A s rot darstellen. Wie finde ich die Farbe? Elche Datei muß ich includen? Das habe ich nie verstanden und das konnte nie ein Erklärbär erklären. Wenn man das weiß kennt man die Hilfe zur Selbsthilfe. Ich will doch irgendwas testen um Spaß zu haben. Ich will alle R suchen in einem Wort. Wie würde ich den Befehl suchen finden? Woher weiß ich ob es den Befehl gibt?
Wieviel Befehle gibts in C? /500/ oder /3.000/? Woher weiß man das? Welche sollte man am Anfang kennen? Solche einfachen fragen hat ein Erklärbär nie erklärt.
Und was ist besser? Eine IDE zu nutzen oder ein Compiler mit der Datei?
Wie testet man Programme? Baut man da extra Programm-Dateien? Oder baut man sie im Programm mit ein?
So einfache Dinge erklärt ein Erklärbär nie.
Das ist so geil XD
Freut mich, dass dir mein Video gefällt!
sehr leicht zu verstehen.top
ich habe bis jetzt fast 5 mal das Video gesehen und immer noch habe ich mit diesem Thema schwierigkeiten ;(
Dann probiere vielleicht mal die Arbeitsaufgaben, die in der Beschreibung verlinkt sind, vielleicht hilft dir das!
Ehrenmann
Sehr gutes Video. Ich finde die Lösungen zu den aufgaben leider nicht.
Unter der Aufgabe müsste ein roter Link mit dem Text "Lösungen" sein.
der datentyp ,, int " vor dem ,,*" bezieht sich nicht auf dem pointer ,,x" sondern nur auf dem ,, *". Datentyp eines jeden pointers ist ,,unsigned int".
* bedeutet nichts anderes als ,,wert in der adresse" .
Und *x bedeutet dass der zeiger auf den wert in der von zeiger gespeicherten adresse zeigt.
Kommt es nicht am Ende darauf an, wie der Wert, der an einer Adresse gespeichert ist, interpretiert wird - oder verstehe ich dein Kommentar falsch?
Na, es sind 3 Jahre her aber hier kommt die triviale Antwort auf deine Frage wieso man bei realloc() den namen des Pointers mitgeben muss: woher soll denn realloc() wissen, zu welchem deiner dutzenden Pointer im Programm es Speicher neuen zuweisen soll? 😅😂
Ich habe vor 2 Jahren bereits eine Antwort nachgereicht (siehe angepinnter Post im Kommentarbereich), aber trotzdem Danke! :) Ich wusste das damals noch nicht, habe es aber dann ergänzt.
Warum manche "freen" sagen ist einfach, manche glauben halt anständig Deutsch zu sprechen und Informatiker zu sein gehe nicht. Finde deine klare Terminologie viel besser danke.
jetzt nochma ohne gayvoice dann isses perfekt
aua wie kann man so peinlich sein 🤣