1

C++の動的メモリ、スタックメモリ、静的メモリの違いを知りたいです。
例としていくつかのコードを次に示します。

#include<iostream>
using namespace std;
char *GetMemory(void)
{
    char p[]="hello world";
    char *q="hello world"; 
    return q;
}
int main(void)
{
    return 0;
} 

なぜ pスタックメモリにあるのにq動的メモリにあるのですか?

4

3 に答える 3

1

スタック メモリの "p" がダイナミック メモリの "q" なのはなぜですか?

それは真実ではない; pとの両方qが自動保存期間で割り当てられます (スタック構造として実装されます)。それらの違いは次のとおりです。

  1. pは配列であり、変更可能なメモリ (割り当てられたスタック) を指します。
  2. qはポインタであり、静的に割り当てられた読み取り専用メモリを指します。あなたは本当にそれを次のように宣言するべきでした:

    const char *p = "なんでも";

ここには動的割り当てはありません。newmalloc、またはメモリを割り当てるために舞台裏でそれらを使用するルーチンを呼び出しませんでした。その結果、p関数が戻ると無効になるため、この関数から戻るのは正しくありません。

于 2012-07-23T03:28:11.477 に答える
1

pqは両方とも変数です。 pタイプは「12 の配列charqで、タイプは「ポインタchar」です。との両方pq自動保存期間があります。つまり、それらはスタックに割り当てられます。

qはポインタであり、文字列の最初の文字を指すように初期化されます"hello world"。この文字列は文字列リテラルであり、すべての文字列リテラルには静的な保存期間があります。

pは配列であるためp、文字列リテラルで初期化すると、文字pの配列が宣言され、初期化されると、文字列リテラルの内容が配列にコピーされます。そのため、GetMemory()が呼び出されると、領域が array のスタックに割り当てられp、文字列リテラルの内容が"hello world"その配列にコピーされます。

コードによって動的割り当てが実行されることはありません。


qは静的記憶域期間を持つ文字の配列へのポインターであるため、関数から安全に戻ることに注意してください。それが指す配列qは、プログラムの全期間にわたって存在します。pただし、p関数が戻ると は存在しなくなるため、 を返すのは安全ではありません。

"hello world"の型が であることにも注意してくださいchar const[12]。C++ には安全でない暗黙的な変換があり、文字列リテラルを文字列リテラルchar*の最初の文字を指すように変換できます。これは const 修飾を暗黙のうちに削除するため、安全ではありません。const char*文字は変更できないため、文字列リテラルを処理するときは常に を使用する必要があります。(C++ 言語の最新リビジョンである C++11 では、この安全でない変換は削除されています。)

于 2012-07-23T03:28:30.717 に答える
0

たとえば、文字列リテラルを使用しているため、これは実行可能ファイルのDATAセグメントに書き込まれる可能性があります。動的メモリは割り当てられていません。より良い例は次のようなものです:

void foo()
{
    //This is a stack variable. Space is allocated 
    //on the stack to store it. Its lifetime is
    //the routine that calls it.

    some_class stack_variable; 

    //This is a heap-allocated variable. It will
    //remain in memory indefinitely unless deleted.
    //If a pointer to this isn't returned, and it
    //isn't deleted by the end of the routine, this
    //will become a "memory leak".

    another_class *heap_variable = new another_class();

    //This is a (method) static variable. It retains its
    //value between method calls

    static int method_static = 1;
    ++method_static;

} 

閉じ中括弧で、stack_variableがクリーンアップされます(つまり、占有していたスタックスペースが再利用されます)。heap_variableは削除されていないため、メモリリークです。このメソッドを数回呼び出すと、次のようになります。

for(int i = 0; i < 5; ++i) { foo(); }

その場合、method_staticの値は5になります。

于 2012-07-23T03:35:22.400 に答える