[Musikwiedergabe] DOUG LLOYD: OK, so ein Vorschlag vor dem Start hier. Wenn Sie das Video auf nicht beobachtet haben Zeiger könnten Sie so zuerst tun. Weil dieses Video ist ein weiterer Arbeitsweise mit Zeigern. Also, es wird zu sprechen über einige Konzepte dass wir in der Deckung Zeiger-Video, und wir sind gehen jetzt über sie zu beschönigen, davon aus, dass sie bereits Art verstanden. Also das ist nur Ihre faire Warnung dass, wenn Sie das Video zu sehen, und Sie nicht gesehen haben die Zeiger Video, könnte es eine Art Fliegen über dem Kopf ein wenig. Und so könnte es besser sein um es in dieser Reihenfolge zu beobachten. So haben wir schon einen gesehen Weg, um mit Zeigern arbeiten, was erklären wir einen variabel, und dann werden wir erklären, eine weitere Variable, einen Zeiger variable Punkte, die zu ihm. Also wir erstellt haben ein Variable mit einem Namen, haben wir erstellt eine zweite Variable mit einem Namen, und wir zeigen, dass zweite Variable in diesem ersten. Diese Art von einen Problem ist aber, weil es erfordert, dass wir genau wissen, wieviel Speicher wir sind gehen, um den Moment brauchen unser Programm kompiliert wird. Warum ist das so? Denn wir müssen in der Lage zu nennen, oder Identifizierung aller möglichen Variablen Wir stoßen könnten. Wir könnten ein Array, das sein könnte haben in der Lage, eine Vielzahl von Informationen zu halten, aber es ist immer noch nicht genau, präzise genug. Was wäre, wenn wir nicht wissen, was ist, wenn wir nicht wissen, wie sehr wir bei der Kompilierung benötigen? Oder was, wenn unser Programm Lauf für eine wirklich lange Zeit, Annahme von verschiedenen Benutzer Daten, und wir können nicht wirklich abschätzen, ob wir sind gehen, um 1.000 Einheiten müssen? Es ist nicht wie wir können, sagen, in der Befehlszeile Geben Sie, wie viele Artikel Sie denken, Sie brauchen. Nun was ist, wenn die Vermutung ist falsch? Dynamische Speicherzuweisung Art ermöglicht uns den Weg um diesem Problem zu erhalten. Und die Art, wie sie es tut ist die Verwendung von Zeigern. Wir können Zeiger zu verwenden, erhalten Sie Zugriff auf dynamisch zugewiesenen Speicher, Speicher, der ist wie Ihr Programm zugewiesen läuft. Es ist nicht während der Kompilierung zugewiesen. Wenn Sie dynamisch zuzuweisen Speicher es aus einem Pool kommt Speicher bekannt als der Haufen. Zuvor der gesamte Speicher wir haben wurde mit im Laufe der Arbeit wurde aus einem Pool worden kommen Speicher bekannt als der Stapel. Eine gute Möglichkeit, in der Regel halten in mind-- und dieser Regel nicht immer zutreffen, aber so ziemlich fast gilt immer true-- ist, dass jede Mal, wenn Sie einen Variablennamen geben lebt wahrscheinlich auf den Stapel. Und immer wenn Sie dies nicht tun geben eine Variable einen Namen, die Sie mit dynamischen Speicher tun können Allokation, lebt es auf dem Heap. Jetzt bin ich Art präsentieren dies als wenn es diese beiden Speicherpools. Aber man kann dies gesehen haben Diagramm, das im Allgemeinen eine Darstellung von Welche Speicher aussieht, und wir werden nicht über all Pflege der Stoff, an der Spitze und der Unterseite. Was uns interessiert, ist dieser Teil in der mittlere hier, Heap und Stack. Wie Sie sehen können, Blick in diesem Diagramm diese tatsächlich nicht zwei separate Pools Speicher. Es ist einer gemeinsamen Pool von Speicher wo Sie beginnen, in diesem visuellen Sie am unteren Rand beginnen und starten Sie füllt sich von unten mit dem Stapel, und Sie Start an der Spitze und starten Auffüllen von oben nach unten mit dem Heap. Aber es ist wirklich die gleichen Pool, es ist einfach verschiedenen Spots, verschiedene Standorte in Speicher, der zugeordnet sind. Und Sie können aus ausführen Speicher entweder mit der Haufen gehen den ganzen Weg nach unten, oder der Stapel gehen den ganzen Weg an die Spitze, oder mit dem Heap und den Stapel treffen aufeinander. Alle diese können Bedingungen dass Ihr Programm verursachen um über genügend Arbeitsspeicher ausgeführt. So sollte man das im Hinterkopf. Wenn wir reden der Heap und der Stapel Wir sind wirklich über die Gespräche gleichen allgemeinen Teil des Speichers, nur verschiedene Abschnitte dieses Speichers. Wie können wir also dynamisch erhalten in erster Linie zugewiesenen Speicher? Wie funktioniert unser Programm zu erhalten Speicher wie es läuft? Nun C bietet eine Funktion namens malloc, Speicherzuweisung, die Sie einen Anruf an, und Sie übergeben wie viele Bytes an Speicher, die Sie wollen. Also, wenn Ihr Programm läuft und Sie wollen eine ganze Laufzeit Sie könnten vier Bytes Mallocks Speicher, malloc Klammern vier. Mallocks durchlaufen Blick durch den Haufen, weil wir dynamisch sind Zuweisen von Speicher, und es wird an Sie zurück ein Zeiger auf diesen Speicher. Es gibt Ihnen nicht, dass memory-- es nicht geben Sie ihm einen Namen, es gibt Ihnen einen Zeiger darauf. Und damit ist, warum wieder sagte ich dass es wichtig ist, vielleicht haben die Zeiger Video angesehen bevor wir zu weit zu bekommen in diese. So malloc ist zu gehen geben Ihnen einen Zeiger zurück. Wenn Mallocks kann man nicht geben, Speicher weil Sie erschöpft haben, es wird Ihnen wieder einen Null-Zeiger. Erinnern Sie sich an, was passiert, wenn wir versuchen und Dereferenzierung eines Null-Zeiger? Wir leiden, eine seg Fehler, nicht wahr? Das ist wahrscheinlich nicht gut. Also jedes Mal, wenn Sie einen Anruf machen um Ihnen immer malloc, immer müssen Sie prüfen, ob die Zeiger gab es Sie zurück ist null. Wenn ja, um Ihr Programm zu beenden müssen Sie weil, wenn Sie versuchen, dereferenzieren der Null-Zeiger Sie gehen einen Segmentierungsfehler leiden und Ihr Programm sowieso abstürzen. Wie können wir also statisch eine ganze Zahl zu erhalten? int x. Wir haben wahrscheinlich das getan ein paar Mal, nicht wahr? Es wird eine Variable namens x, die auf dem Stapel lebt. Wie können wir dynamisch eine ganze Zahl zu erhalten? Int Sterne px gleich malloc 4. Oder passender wir sagen würden int Sterne px gleich malloc Größe int, um nur einige wenige zu werfen magischen Zahlen rund um unser Programm. Das wird für uns zu erhalten vier Byte, aus dem Haufen, und der Zeiger wir bekommen zurück, um es genannt wird px. Und dann, so wie wir haben zuvor wir getan kann dereferenzieren px zu auf diesen Speicher zugreifen. Wie können wir eine ganze Zahl von Benutzer zu bekommen? Wir können sagen, int x gleich zu int. Das ist ziemlich einfach. Was, wenn wir um ein Array erstellen möchten von x Schwimmer, die auf dem Stack zu leben? schweben stack_array-- das ist der Name unserer array-- eckigen Klammern x. Das wird für uns ein Array zu erstellen X Schwimmer, der auf dem Stapel zu leben. Wir können eine Reihe von Schwimmern zu erstellen daß wohnt auf dem Heap, auch. Die Syntax aussehen könnte ein etwas umständlich, aber wir können sagen, float Sterne heap_array gleich malloc x mal die Größe des Schwimmers. Ich muss genug Platz, um zu halten x Fließkommazahlen. Also sage ich brauche 100 Schwimmer, oder 1.000 Schwimmern. So dass in diesem Fall wäre es 400 Bytes für 100 Wagen, oder 4.000 Bytes für 1.000 Wagen, weil jeder Schwimmer nimmt vier Bytes Speicherplatz. Nach dem Handeln dies kann ich das verwenden eckigen Klammer-Syntax auf heap_array. Gerade als ich auf stack_array, I können ihre Elemente einzeln zugreifen Verwendung heap_array Null heap_array ein. Aber erinnern an den Grund, warum wir das tun können ist, weil der Name eines Arrays in C ist wirklich ein Zeiger auf erste Element, das Arrays. Also die Tatsache, dass wir erklären ein Reihe von Schwimmern auf dem Stapel hier ist eigentlich etwas irreführend. Wir sind wirklich in der zweite Codezeile gibt schafft auch einen Zeiger auf einen Batzen Speicher, die wir dann einige Arbeit mit. Hier ist das große Problem mit dynamisch zugewiesenen Speicher aber, und aus diesem Grund ist es wirklich wichtig, einige gute Gewohnheiten zu entwickeln wenn Sie mit arbeiten daran. Im Gegensatz zu statisch deklariert Gedächtnis, Ihr Gedächtnis wird nicht automatisch an die zurück System, wenn Ihre Funktion ist getan. Wenn wir also Haupt und Haupt ruft eine Funktion f, wenn f Oberflächen, was auch immer er tut und gibt die Steuerung des Programms zurück zur Hauptansicht, der gesamte Speicher dass f verwendet wird zurück gegeben. Es kann wieder verwendet werden von einem anderen Programm, oder eine andere Funktion, wird später im Haupt genannt. Es kann das gleiche Speicher immer wieder zu verwenden. Wenn Sie dynamisch Speicher zuweisen, obwohl Sie müssen also explizit sagen, die System, dass Sie damit fertig sind. Es wird auf die für Sie zu halten, der konnte führen zu einem Problem von euch laufen des Speichers. Und in der Tat haben wir manchmal beziehen dies als ein Speicherleck. Und manchmal sind diese Speicherlecks kann eigentlich wirklich verheerend sein für die Systemleistung. Wenn Sie häufig Internet-Benutzer sind Sie können bestimmte Web-Browser verwenden, und ich werde Namen hier nicht nennen, aber gibt es einige Web-Browser da draußen , die berüchtigt für tatsächlich mit sich Speicherlecks, die nicht festgelegt zu tun bekommen. Und wenn Sie Ihren Browser offen lassen für eine sehr lange Zeitdauer, Tage und Tage oder Wochen, Sie manchmal vielleicht, dass Ihr System feststellen, ist wirklich läuft, wirklich langsam. Und der Grund dafür ist, dass der Browser Speicher zugewiesen, aber dann das System nicht gesagt, dass es damit fertig. Und so, dass weniger Speicher verlässt für alle anderen Programme zur Verfügung zu haben, um zu teilen, weil Sie leaking-- dass Web-Browser Programm ist undicht Speicher. Wie kommen wir zu geben Speicher zurück wenn wir mit ihr geschehen? Nun zum Glück ist es ein sehr einfache Möglichkeit, es zu tun. Wir befreien es einfach. Es gibt eine Funktion frei genannt, es nimmt einen Zeiger auf eine Speicher, und wir sind gut zu gehen. Also lassen Sie uns sagen, dass wir in der du mitten in unserem Programm, wir wollen zu 50 Zeichen malloc. Wir wollen, um ein Array, das kann malloc der Lage ist, 50 Zeichen. Und wenn wir einen Zeiger zurück zu dass dieser Zeiger ist der Name das Wort. Wir tun, was wir sind gehen, um mit Wort zu tun, und dann, wenn wir getan wir frei es einfach. Und jetzt haben wir jene 50 zurück Byte des Speichers an das System zurück. Einige andere Funktion können sie benutzen. Wir müssen nicht über das Leiden ein Sorgen Speicherleck, weil wir das Wort befreit. Wir haben die Erinnerung zurück gegeben, so dass wir fertig sind mit ihm arbeiten. So gibt es drei goldenen Regeln Das sollte im Auge behalten, wenn Sie werden, die dynamische Zuweisung von Speicher mit malloc. Jeder Speicherblock, Sie müssen malloc befreit werden bevor Ihr Programm Ausführung beendet. Jetzt wieder in das Gerät oder in die IDE diese Art der Fall für Sie auf jeden Fall wenn Sie-- dies trotzdem geschehen, wenn Ihr Programm beendet wird, der gesamte Speicher wird freigegeben. Aber es ist in der Regel eine gute Codierung Praxis, immer, wenn Sie fertig sind, zu befreien, was Sie mallocd haben. Das heißt, nur Dinge, die Sie haben mallocd sollte befreit werden. Wenn Sie statisch deklarieren integer, int x Semikolon daß wohnt auf dem Stapel, die Sie dann nicht wollen x befreien. So einzigen Dinge, die Sie haben, mallocd sollte befreit werden. Und schließlich, nicht frei etwas zweimal. Das kann dazu führen, eine weitere seltsame Situation. Also alles, was Sie haben, mallocd muss befreit werden. Nur Dinge, die Sie haben, malloc sollte befreit werden. Und nicht frei etwas zweimal. Also lassen Sie uns durch ein Beispiel gehen Sie hier von dem, was einige dynamisch zugewiesen Speicher könnte wie gemischte aussehen in mit einigen statischen Speicher. Was könnte hier geschehen? Sehen Sie, wenn Sie folgen können, entlang und erraten, was ist passieren, wie wir gehen durch alle diese Zeilen Code. Also sagen wir int m. Was passiert hier? Gut, das ist ziemlich einfach. Ich erstelle eine Integer-Variable namens m. I Farbe es Grün, denn das ist die Farbe dass ich, wenn ich rede zu Integer-Variablen. Es ist eine Box. Es heißt m, und Sie können Shop Zahlen darin. Was, wenn ich dann sage int a star? Nun, das ist ziemlich ähnlich. Ich erstelle eine Box genannt. Es ist in der Lage, Halte int Sterne, Zeigern auf Integer. Also werde ich es Färbung grün-ish auch. Ich weiß, es hat etwas mit einer Ganzzahl machen, aber es ist nicht selbst eine ganze Zahl. Aber es ist so ziemlich das gleiche Idee. Ich habe eine Box erstellt. Beides rechts leben jetzt auf dem Stapel. Ich habe sie beide Namen angegeben. int star b gleich malloc Größe des int. Dieses könnte ein wenig schwierig sein. Nehmen Sie sich die Zeit und überlegen Sie, was Sie würde erwarten, dass in diesem Diagramm passieren. int star b gleich malloc Größe des int. Gut, das ist nicht nur eine Box zu erstellen. Das schafft eigentlich zwei Boxen. Und es bindet, sie legt auch ein Punkt in einer Beziehung. Wir haben nur einen Block zugeordnet Speicher auf der Halde. Beachten Sie, dass das Feld oben rechts es hat keinen Namen. Wir mallocd es. Es gibt auf dem Heap. Aber b hat einen Namen. Es ist eine Zeigervariable namens b. Die das Leben auf dem Stapel. So ist es ein Teil des Speichers Das deutet auf einen anderen. b enthält die Adresse dieser Speicherblock. Es macht keinen Namen anders. Aber darauf zeigt. Wenn wir also sagen int star b gleich malloc Größe int, dass genau dort, dass Pfeil, der oben auf dem geknallt rechten Seite gibt, dass ganze Sache, Ich werde es scheinen, wieder ist, was passiert. All das passiert in dass einzige Zeile Code. Jetzt werden wir etwas mehr bekommen einfach erneut. a gleich Et-Zeichen m. Wissen Sie, was ein Rückruf gleich Ampersand m? Nun, das ist ein bekommt m Adresse. Oder setzen mehr schematisch, ein Punkte auf m. a gleich b. OK also hier ist eine andere. A gleich b. Was wird passieren auf das Diagramm dieses Mal? Nun erinnern, dass die Zuweisungsoperator Werke durch Zuweisung des Wertes auf die Rechts auf dem Wert auf der linken Seite. Anstatt also eine Zeige zu m, a jetzt zeigt auf der gleichen Stelle, dass b Punkten. a zeigt nicht auf B, A Punkte, an denen b Punkten. Wenn ein spitzen zu, dass B freut waren ein kaufmännisches Und gleich b. Aber anstatt a gleich b gerade bedeutet, und b sind jetzt Hinweis an die gleiche Adresse, denn Innere b ist nur eine Adresse. Und nun Innenseite a die gleiche Adresse. m gleich 10 ist, wahrscheinlich die Die einfachste Sache, wir in ein wenig getan. Legen Sie die 10 in der Box. Stern b gleich m sowie 2, erinnern von unsere Zeigern Video Was star b bedeutet. Wir sind zu dereferenzieren b und legte los einige Wert in dieser Speicherstelle. In diesem Fall 12. Also, wenn wir dereferenzieren Punkt erinnern wir uns nur die Reise nach unten auf den Pfeil. Oder anders ausgedrückt, wir gehen Sie zu dieser Speicheradresse und wir manipulieren in irgendeiner Weise. Wir haben einen gewissen Wert in es. In diesem Fall Sterne-b gleich m plus 2 ist nur gehen Sie auf die Variable, auf die durch b, gehen Sie zu dem Speicher, auf den b, und legte m plus 2 drin, 12. Kostenlos I b. Was passiert, wenn ich frei b? Denken Sie daran, was ich gesagt habe freie Mittel. Was sage ich, wenn ich frei b? Ich bin fertig mit ihm arbeiten, nicht wahr? Ich gebe im wesentlichen den Speicher. Ich gebe es an das System zurück. Ich brauche das nicht mehr ist was ich ihnen zu sagen, OK? Nun, wenn ich sage, ein Sterne- gleich 11 können Sie wahrscheinlich jetzt schon sagen, dass etwas Schlimmes wird hier passieren, oder? Und in der Tat, wenn ich versuchte, dass ich wahrscheinlich würde einen Segmentation Fault zu leiden. Denn jetzt, wenn auch zuvor, dass Teil des Speichers war etwas, das ich hatte Zugang zu diesem Zeitpunkt jetzt bin ich den Zugriff auf Speicher, ist nicht legal für mich zu öffnen. Und so werden wir wahrscheinlich erinnern, wenn wir auf Speicher dass wir sollen nicht zu berühren, das ist die häufigste Ursache eines Segmentierungs Fehler. Und so mein Programm würde abstürzen, wenn ich versuchte, dies zu tun. Also noch einmal, es ist eine gute Idee, eine gute zu bekommen Praxis und gute Gewohnheiten verwurzelt bei der Arbeit mit malloc und free, so dass Sie die Segmentierung nicht leiden Fehler, und dass Sie verwenden Ihre dynamisch zugewiesenen Speicher verantwortlich. Ich bin Doug Lloyd dies CS50.