2

新しい演算子をより詳しく理解しようとしています。ヒープからメモリを割り当て、メモリへのポインタを返すという事実を理解しています。私の質問は、ポインタを取得し、それを使用して別の宣言された変数への別のポインタを格納すると、値のコピーまたはによって示される値はどのように発生するのかということです。だから例えば

変数を宣言します

int x = 4;

そして、言います

int* ptr = new int;
ptr = &x;

ptrは、ヒープからのメモリのチャンクを指します。xは、メモリの個別のチャンクを所有するスタックで定義されます。ptrとxのアドレスは同じです。ptrを削除しても、xはまだメモリに存在するため、有効です。* ptrと言うとき、ptrが指す値(この場合は4)を探しています。私の質問は4ですが、それはどこにありますか。それは2つの別々のメモリチャンクに存在しますか?1つはxで表され、もう1つはnewから取得したものです。プロセスはどのように行われますか?4は2つのチャンク間でどのように送信されますか、またはsthgがありませんか?助けてください。

また、ptr =&xと言うとき、それはビット単位のコピーです。言い換えると、ヒープを介してアクセスしたばかりのメモリを永久に失うのでしょうか。

4

3 に答える 3

6
int* ptr = new int;
ptr = &x;

ptrは、ヒープからメモリのチャンクをポイントします

いいえ、そうではありません。割り当て後、自動ストレージxを持つ変数のアドレスを指します。によって最初にポイントされた動的に割り当てられたハンドルを失ったため、削除できなくなりました。メモリの「チャンク」を介して送信されることはありません。を参照解除すると、xによって参照される変数を取得します。この変数は値を保持します。intptr4ptr4

この例を試してください:

#include <iostream>

int main()
{

  int x = 4;
  int* ptr = new int;
  ptr = &x;  // lose handle on dynamically allocated int: MEMORY LEAK
  std::cout << (*ptr) << "\n";
  x += 1;
  std::cout << (*ptr) << "\n";
  (*ptr) += 1;
  std::cout << x << "\n";

}
于 2012-09-16T17:09:29.057 に答える
2

あなたが見たように、あなたはあなたが望むどんなアドレスでも指すことができptrます、しかしそれはそれが安全であるという意味ではありません。ここでは、に割り当てられたメモリnewがによってポイントされておらず、孤立しているため、間違ったメモリ操作を行っていますptr。これは言語によって許可されていますが、安全ではありません。

したがって4、スタック上の同じアドレスにまだ存在しているのは、ptr実行した後にaによっても参照されているということだけですptr=&x;

于 2012-09-16T17:14:07.463 に答える
2

「スタック」と「ヒープ」を忘れてください。それはあなたが理解する必要があることにとって重要ではありません。

C ++のオブジェクトには、静的、動的、自動の3つの異なるストレージクラスのいずれかがあります。

自動オブジェクトと静的オブジェクトは、非参照変数の値であるオブジェクトです。より正確には、名前空間スコープの変数とブロックスコープの静的変数は静的オブジェクトを保持し、ブロックスコープの非静的変数は自動オブジェクトを保持します。これらのオブジェクトの存続期間は、ソースコード内のそれらの位置によって決まります。

// file.cpp

int a;             // static, global (= "namespace scope")

void foo()
{
    static int b;  // static, block scope

    int c;         // automatic (always block scope)
}


対照的に、動的オブジェクトは、式の結果として作成されるオブジェクトですnew。動的オブジェクト自体が変数になることはありません。それらを取得するには、ポインター(それ自体がオブジェクト)または参照変数(参照はオブジェクトではありません)を介してのみ取得できます。

Foo * p = new Foo;
Foo & q = *new Foo;  // NEVER do this!

動的オブジェクトは、それらへのポインターを介して明示的に削除するまで存続します。

delete p;    // normal
delete &q;   // works, but insane

あなたの場合、new intタイプの新しい動的オブジェクトを作成し、intこのオブジェクトへのポインタを変数に格納しますptr。ただし、次の行で変数を上書きし、動的整数へのポインターを失います。オブジェクトがリークされ、回復できなくなりました。

于 2012-09-16T17:15:11.560 に答える