[音楽再生] DOUG LLOYD:OKそう提案 ここで開始する前に。 あなたは上のビデオを見ていない場合 あなたが最初にそうすることができますポインタ。 このビデオであるため、他の ポインタでの作業の方法。 だから、話をするつもりです いくつかの概念について 我々はにカバーすること ポインタ映像、私たちはしています 、ここでそれらをごまかすつもり 彼らはすでにしていると仮定 理解の一種。 だから、ちょうどあなたの公正な警告です あなたはこのビデオを見ている場合に あなたが見ていません ポインタ映像、それは一種のかもしれません あなたの頭の上に少し飛びます。 そしてそれは良いかもしれません そのためには、それを見て。 だから我々はすでに1を見てきました ポインタで動作するための方法、 これは私たちが宣言されています 変数、し、我々 別の変数、ポインタを宣言 変数は、それはそれを指しています。 だから我々は、作成しました 名前の変数は、我々はしました 名前の第二の変数を作成し、 我々は、第2の変数を指します その最初は。 この種の持っています 問題しかし、それ理由 正確に知るために私たちを必要とします どのくらいのメモリ、我々はしています 瞬間が必要になります 私たちのプログラムがコンパイルされます。 何故ですか? 私たちは名前をできるようにする必要があるためか、 可能なすべての変数を識別 我々は発生する可能性があります。 私たちはあるかもしれない配列を持っている可能性があります 多くの情報を保持することができ、 それはまだありません 十分正確に正確な。 私たちは知っていない場合は、 私たちは考えている場合 我々は、コンパイル時にどのくらいが必要になるでしょうか? あるいは、どのような私たちのプログラムがする場合 本当に長い時間のために実行、 さまざまなユーザーを受け入れます データ、私たちは本当にすることはできません 私たちがしているかどうかを見積もります 1,000台が必要になりますか? それは、我々はできるようではありません コマンドラインで言います どのように多くの項目を入力します。 あなたが必要と思います。 まあその推測は何が間違っている場合は? 動的メモリ割り当て ソートの私たちに道を可能にします この特定の問題を回避します。 そして、方法は、それはそれをしません ポインタを使用することです。 我々は、へのポインタを使用することができます 動的にアクセスします 割り当てられたメモリ、メモリ あなたのプログラムとして割り当てが実行されています。 これは、コンパイル時に割り当てられていません。 あなたが動的に割り当てると それはプールから来るメモリ メモリのヒープとして知られています。 私たちがきたこれまでのすべてのメモリ コー​​ス内で仕事をして プールから来てされています メモリのスタックとして知られています。 一般的に良い方法 mind--と、このルールに保ちます 常に、真の保持していません しかし、かなりのほとんど 常にtrue--が任意の点である保持 時間は、変数名を与えます おそらくスタック上に住んでいます。 そうしないと、いつでも 変数に名前を付け、 あなたは、動的なメモリを行うことができます 割り当ては、ヒープ上に住んでいます。 今、私は一種のとしてこれを提示しています メモリのこれら2つのプールがあるかどうか。 しかし、あなたはこれを見ている可能性があります 一般的に図、 の表現 どのメモリは次のようになります、 我々はについてのすべての世話をするつもりはありません 上部と下部のもの。 私たちが気にすることで、この部分です ここで、中間、ヒープとスタック。 あなたがすることによって見ることができるように この図を見て、 これらは、実際には2つのではありません メモリの別々のプール。 これは、メモリの1共有プールです どこにこの視覚的に開始します あなたは底に開始します そして、いっぱい開始 スタックと下部、およびあなたから 上部に開始し、いっぱい開始 ヒープで上から下。 しかし、それは実際にあります 同じプールには、それだけです 異なるスポットを、異なる場所 メモリに割り当てられていること。 そして、あなたは外に実行することができます 有するかによってメモリ ヒープはすべての道を行きます 下へ、または持っています スタックは、一番上にすべての道を行きます またはヒープとスタックを持ちます お互いに会います。 それらのすべての条件とすることができます それはあなたのプログラムを引き起こします メモリが不足しています。 だから、心の中でそれを維持します。 我々はについて話すとき ヒープとスタック 私たちは本当に話しています ただメモリの同じ一般的なチャンク、 そのメモリの異なる部分。 どのようにして動的に取得するのですか 最初の場所で割り当てられたメモリを? どのように私たちのプログラムは、取得しません それが実行しているように、メモリ? ウェルCと呼ばれる機能を提供 malloc関数、メモリアロケータ、どの あなたはへの呼び出しを行い、あなたは渡します どのように多くのあなたがしたいメモリのバイト。 だからあなたのプログラムが実行されている場合 あなたは整数ランタイムをしたいです、 あなたは、4つのバイトをマロック可能性があります メモリは、malloc関数は、4つの括弧します。 マロックは通過します ヒープを通して見て、 我々は動的だから メモリを割り当てます、 そしてそれはあなたに戻ります そのメモリへのポインタ。 それはあなたにそれを与えるものではありませんmemory-- それはそれに名前を与えるものではありません、 それはあなたにそれへのポインタを提供します。 再び私が言った理由となるようです それは多分に重要だということ ポインタのビデオを見ています 我々はこの中に遠く取得する前に。 だから、malloc関数に起こっています ポインタをあなたにお返し。 マロックはあなたに与えることができない場合 メモリあなたが実行したので、 それはNULLポインタをあなたに戻ってあげます。 あなたは私たちとどうなるか覚えていますか 試してみて、NULLポインタ間接参照? 我々は右、ワンセグ障害に苦しみますか? それはおそらく良いではありません。 だから、毎回あなたが電話をかけます いつも、いつもあなたををmallocします かどうかを確認する必要があります それはあなたが戻ってnullで与えたポインタ。 もしそうであれば、あなたのプログラムを終了する必要があります あなたがしようと間接参照しまうと あなたが行っているNULLポインタ セグメンテーションフォールトに苦しみます あなたのプログラムがあります とにかくクラッシュするだろう。 それでは、どのよう静的に我々を行います 整数を取得しますか? int型のx。 我々は、おそらくそれをやりました 回の束、右? これは、という変数を作成します。 スタック上に住んでいるのx。 どのように動的に整数を得るのですか? int型のスターPXはmalloc関数4に等しいです。 あるいは、より適切 我々は、int型のスターPXを言うと思います int型のmalloc関数のサイズに等しく、 ただ、いくつかの少ないをスローします 私たちのプログラムの周りのマジックナンバー。 これが私たちのために取得しようとしています ヒープからの4バイトのメモリ、 ポインタは、我々が得ます それに戻っては、ピクセルと呼ばれています。 そして、我々は同じようにしました 我々は以前に行われ 缶PX逆参照 そのメモリにアクセスします。 どのように我々は、ユーザから整数を得るのですか? 私たちは、int型xはint型を取得するに等しいと言うことができます。 これはかなり簡単です。 私たちは、アレイを作成したい場合はどう スタック上に住んでいるのx山車の? フロートはそれが名前ですstack_array-- 私たちのarray--角括弧xの。 それが私たちのために配列を作成します スタック上に住んでいるのx山車の。 私たちは、floatの配列を作成することができます それも、ヒープ上に住んでいます。 構文は次のとおりになります。 もう少し面倒、 しかし、我々はfloatを言うことができます スターheap_arrayに等しいです malloc関数のx倍フロートのサイズ。 私は保持するのに十分なスペースを必要とします X浮動小数点値。 だから私は100を必要とすると言います フロート、または千山車。 だから、その場合には、それは次のようになります 100フロート400バイト、 千フロートまたは4,000バイト、 各フロートが占めるため、 スペースの4バイト。 これを実行した後、私は使用することができます heap_arrayの角括弧構文。 ちょうど私がstack_arrayの場合と同じように、私 個別の要素にアクセスすることができます heap_arrayゼロ、heap_arrayいずれかを使用。 しかし、我々はそれを行うことができた理由を思い出します であるため、C言語の配列の名前 本当にへのポインタであります その配列の最初の要素。 私たちは宣言しているという事実そう ここで、スタック上のfloatの配列 実際に少し誤解を招く恐れがあります。 私たちは本当にしています そこにコードの2行目 またのチャンクへのポインタを作成します 私たちは、その後にいくつかの作業を行うメモリ。 ここでの大きな問題です 動的にかかわらず、メモリが割り当てられ、 これはそれが本当にだ理由です いくつかの良い習慣を開発することが重要 あなたはそれで作業しているとき。 静的に宣言とは異なり、 メモリ、あなたの記憶 自動的に戻されません あなたの関数が実行されるシステム。 だから我々は、メインがある場合、および メインは、関数を呼び出します それはF仕上げをやっているものは何でもF、 プログラムの制御を戻します バックメインに、すべてのメモリ 使用されているfはバック与えられています。 再度使用することができます 他のプログラムによって、 またはいくつかの他の機能、その 主に後に呼び出されます。 それは何度も、同じメモリを使用することができます。 あなたの場合、動的に しかしメモリを割り当てます あなたが明示的に指示する必要があります あなたはそれで行われているシステム。 それは可能性が、あなたのためにその上に保持します あなたが不足しての問題につながります メモリの。 そして、実際には、我々は時々参照してください。 メモリリークとしてこれに。 そして、時には、これらのメモリリーク 実際には本当に壊滅的なことができます システムパフォーマンスのため。 あなたが頻繁にインターネットユーザーの場合 あなたは、特定のWebブラウザを使用する場合があります そして、私はここで名前を命名しませんが、 一部のWebブラウザは、そこにあります 実際に持つことで有名であること 固定されませんメモリリーク。 そして、あなたは、あなたのブラウザが開いているままにしておくと 時間の非常に長い期間のために、日 数日、または数週間、時には お使いのシステムことがわかります 本当にゆっくりと、本当に実行されています。 そして、その理由は、ということです ブラウザは、メモリを割り当てました しかし、システムを聞いていません ことそれはそれで行われています。 そして、そのためには、少ないメモリを残し あなたの他のプログラムのすべてのために利用可能 あなたがしているので、共有する必要がします そのウェブブラウザleaking-- プログラムがメモリをリークしています。 我々は戻って、メモリを与えるにはどうすればよいです 我々はそれを行っているとき? まあ幸いです それを行うには非常に簡単な方法。 我々はそれを解放します。 自由と呼ばれる機能があります、 これは、メモリへのポインタを受け取り、 私たちは行ってもいいです。 それでは、私たちがしているとしましょう 私たちのプログラムの途中、 私たちは50文字をmallocしたいです。 我々はできる配列ををmallocしたいです 50文字を保持することができます。 そして、我々は戻っへのポインタを取得するとき それは、そのポインタの名前は言葉です。 私たちはしているものは何でも 単語をどうするつもり、 し、我々をしているとき 私たちはそれを解放して行わ。 そして今、我々はそれらの50を返しました バックシステムへのメモリのバイト。 他のいくつかの機能は、それらを使用することができます。 私たちは苦しみを心配する必要はありません メモリリークは、私たちは言葉を解放しているため。 我々は戻って、メモリを与えてくれました、 私たちはそれで作業完了です。 だから3つがあります そのすべき黄金のルール あなたがしている時はいつでも心に留めておきます 動的にメモリを割り当てます malloc関数と。 そのメモリの各ブロック あなたのmallocを解放する必要があります あなたのプログラムの前に実行を終了します。 ここでもう一度、アプライアンス内またはで IDEは、この種の、とにかくあなたのために起こります you--とき、これはとにかくどうなります あなたのプログラムが終了すると、 すべてのメモリが解放されます。 しかし、それは一般的に良いコーディングです 実際、常に、設定が完了したら、 あなたがmallocdたものを解放します。 それによると、唯一のものは、 あなたは解放する必要がmallocdました。 あなたは静的に宣言すると 整数、int型のx、セミコロン、 あなたは、スタック上に住んでいます その後、Xを解放する必要はありません。 あなたがきたので、唯一のもの mallocdを解放する必要があります。 そして最後に、二回無料ではない何かをします。 それがにつながることができます 別の奇妙な状況。 あなたがきたそうすべて mallocdを解放する必要があります。 あなたがた唯一のもの malloc関数を解放する必要があります。 そして二度ではない自由な何かをします。 それでは、ここでは例を挙げて行ってみよう いくつかは動的に割り当てられたものの メモリは、混合のようになります。 いくつかのスタティック・メモリとインチ ここで何が起こるのでしょうか? あなたが続くことができるかどうかを確認 沿って、何がだと思います 私たちが行くように起きよう コー​​ドのすべてのこれらのラインを介して。 だから我々は、int型のメートルを言います。 ここで何が起こりますか? まあ、これは非常に簡単です。 私はメートルと呼ばれる整数型の変数を作成します。 私は、それが緑色 なぜならそれは色です 私が話しているとき、私は使用していること 約整数変数。 それは箱です。 これはMと呼ばれ、次のことができます その中の整数を格納します。 私は、int型のスターは何と言えば? まあそれはかなり似ています。 私はと呼ばれるボックスを作成しています。 これは、int型を保持することができるのです 星、整数へのポインタ。 だから私は、同様に緑っぽいそれを着色しています。 私はそれが何かを持っている知っています 整数を行うには、 それは整数そのものではないのです。 しかし、それはほとんど同じ考えです。 私はボックスを作成しました。 これらの権利の両方 今スタック上に住んでいます。 私は彼らに両方の名前を与えてくれました。 int型のスターBは、int型のmallocの大きさに等しいです。 この1は少しトリッキーなことがあります。 秒を取り、あなたはどうなんだと思います この図に起こることを期待します。 int型のスターBは、int型のmallocの大きさに等しいです。 まあこれは単に一つの箱を作成しません。 これは実際に2つのボックスを作成します。 そしてそれはまた、確立し、結び付け 関係のポイント。 私たちは一つのブロックを割り当てられました ヒープ上のメモリ。 右上のボックスことに注意してください 名前がありません。 我々はそれをmallocd。 これは、ヒープ上に存在します。 しかし、bが名前を持っています。 これは、Bと呼ばれるポインタ変数です。 それはスタック上に住んでいます。 だから、メモリの一部です それはまた別の1を指します。 Bは、アドレスが含まれています メモリのそのブロックの。 それ以外の場合は名前がありません。 しかし、それはそれを指しています。 だから我々は、int型のスターbが等しいと言うとき int型のmalloc関数の大きさ、その右が、 上のポップアップその矢印 そこに右側、その全部、 私はそれが表示される必要があります もう一度、何が起こるかです。 そのすべてがで起こります コー​​ドの一行。 今、私たちは少し多くを得るでしょう 再び簡単な。 アンパサンドメートルに等しいです。 あなたは何を思い出してください アンパサンドmが等しいですか? まあそれはメートルのアドレスを取得します。 あるいは、より図式入れます メートルを指します。 Bに等しいです。 [OK]をので、ここでは別のものです。 AがBに等しいです。 何が起こるだろう この時の図に? まあことを思い出してください 代入演算子の作品 上の値を割り当てることによって、 右、左の値に設定します。 だからではなくメートルを指しての、今 Bポイントが同じ場所を指しています。 、B点はありません B点を指しています。 そのでしょうBに指されました アンパサンドBに等しいされています。 しかし、その代わりに、単にBに等しいです それを意味し、bは今あります 、同じアドレスを指しているため、 Bの内側にだけアドレスです。 そして今の内側に同じアドレスです。 mは、おそらく、10に等しいです 最も簡単なもの 我々は少しで行ってきました。 ボックスに10を入れてください。 スターBはMに等しいプラス2からリコール 私たちのポインタビデオどの星bが意味しています。 私たちは、間接参照Bと置くつもりです そのメモリ位置にあるいくつかの値。 この場合、12で。 だから、ときに我々のポイントを間接参照 私達はちょうど矢印を下に移動思い出します。 あるいは、別の言い方をすれば、我々 そのメモリアドレスに移動 そして、我々はいくつかの方法でそれを操作します。 私たちはそこにいくつかの値を入れます。 この場合、スターBに メートルに等しいプラス2だけです 変数に行くには、Bによって指さ メモリに行くには、Bによって指さ そして、、そこに12メートルプラス2を置きます。 今、私はBを解放します。 私はBを解放すると、どうなりますか? 私は自由な手段を言ったことを覚えておいてください。 私はBを解放するとき、私は何を言っていますか? 私はそれで作業終わりですよね? 私は基本的にメモリを放棄します。 私は、それをシステムに返します。 私は、これはもうである必要はありません 私はOK、それらを言っていますか? 今、私はと言えばスターA 11あなたはおそらくすることができます等しいです 既に悪いこと何かを伝えます 右、ここで起こるだろうか? そして、私はそれ私はおそらくしようとした場合、実際に セグメンテーションフォールトを被ることになります。 今、あるがため、 メモリの以前にそのチャンク 私が持っていたものでした この時点でのアクセス、 今私はそのメモリにアクセスしてい 私がアクセスするための法的ではありません。 そして、我々は、おそらくれるように 我々はメモリにアクセスリコール、 私たちが触れることになっていないこと、 それは、最も一般的な原因です セグメンテーションの 障害が発生しました。だから私のプログラム 私はこれを行うにしようとした場合クラッシュしていました。 だから、もう一度、それは良いを取得することをお勧めします 実践と良い習慣が根付い mallocとfreeで作業する場合、 あなたは、セグメンテーションを受けないように 故障、およびあなたが使用することを あなたの動的に割り当てられました メモリ責任。 私は、これはCS50であるダグ・ロイドです。