1. ホーム
  2. c++

[解決済み] C++でスタックとヒープを正しく使うには?

2022-07-28 11:56:30

質問

私はプログラミングの経験がありますが、主にJavaとC#を使用しています。私は実際に自分自身でメモリを管理する必要があったことはありません。最近 C++ でプログラミングを始めましたが、いつスタックに格納し、いつヒープに格納するのか、少し混乱しています。

私の理解では、非常に頻繁にアクセスされる変数はスタックに格納されるべきで、オブジェクト、めったに使用されない変数、および大規模なデータ構造はすべてヒープに格納されるべきであると思います。これは正しいのでしょうか、それとも私が間違っているのでしょうか。

どのように解決するのですか?

いいえ、スタックとヒープの違いはパフォーマンスではありません。関数内のローカル変数 (malloc() や new を使用しないもの) はすべてスタックに格納されます。関数内のローカル変数(malloc()やnew以外のもの)はスタック上に存在し、関数から戻ると消滅します。もし何かを宣言した関数よりも長く生きさせたいのであれば、ヒープ上に割り当てる必要があります。

class Thingy;

Thingy* foo( ) 
{
  int a; // this int lives on the stack
  Thingy B; // this thingy lives on the stack and will be deleted when we return from foo
  Thingy *pointerToB = &B; // this points to an address on the stack
  Thingy *pointerToC = new Thingy(); // this makes a Thingy on the heap.
                                     // pointerToC contains its address.

  // this is safe: C lives on the heap and outlives foo().
  // Whoever you pass this to must remember to delete it!
  return pointerToC;

  // this is NOT SAFE: B lives on the stack and will be deleted when foo() returns. 
  // whoever uses this returned pointer will probably cause a crash!
  return pointerToB;
}

スタックが何であるかをより明確に理解するために、反対側からそれを見てみましょう。高レベル言語の観点からスタックが何をするかを理解しようとするのではなく、"call stack" と "calling convention" を調べて、関数を呼び出すときにマシンが実際に何をするかを見てみてください。コンピュータのメモリは一連のアドレスに過ぎず、ヒープとスタックはコンパイラが発明したものです。