2017-06-11 13 views
0

私はCプログラムのメモリ管理を学んでいます。私は良い疑いに着いた。 (UbuntuのOS)malloc()|スタックアドレスとヒープ位置のメモリアドレス長の差| Cプログラミング

マイ・ダウト:

私は、スタック内とヒープの両方内にあるデータのアドレスを知りたいと思いました。しかし、私はそれらのアドレスを印刷しようとしたとき、私はアドレスの長さが異なることを観察した! ここで、ヒープアドレスよりも長いスタックアドレスを表示するのはなぜですか?プロセスごとのスタックメモリは、固定およびヒープメモリよりも少ない

  • :私が知っている

  • のmalloc()メモリは、ヒープ
  • ローカル変数に割り当てるあなたも私の疑問に答えることができるように私はここに私のデモコードを入れ

スタックに行きます。

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int *ptr; // goes on stack 

    ptr = (int *)malloc(sizeof(int)); 
    *ptr = 10; // 10 is stored on heap 
    printf("%p : heap address\n",ptr); 
    printf("%p: stack address\n",&ptr); 
    return 0; 

} 

出力: 私はだから今あなたは私が求めていますかを理解かもしれない、私の端末で出力

0x1ea2010 : heap address 
0x7ffda62cb3c0: stack address 

を以下ました。スタックアドレスの長さがヒープより長いのはなぜですか?ヒープは大きなメモリプールなので、明らかに長さは長くなければなりません。

スタックとヒープの割り当てが同じメモリブロックで行われている場合(現代のOSのように..どこかでこれを読んでいます)、同じ長さにする必要があります。

大丈夫です。私の記憶の概念を透明にするのを助けてください。

注:私の疑いが非常に単純または愚かな場合は、少なくとも私のデモコードと異なる長さのアドレスの背後にある魔法でどのようにメモリ割り当てが行われたか教えてください。

このような投稿をお読みいただきありがとうございます。ハッピーアンサーリング!

+0

これらは、印刷している仮想アドレスだけです。ダイナミックリンクのためにメモリの実際の物理アドレスを特定することはできません。私が間違っているなら誰か私を修正してください。 –

+0

'%p'変換タイプ指定子に関するC標準から:"ポインタの値は**実装定義の**方法で印刷文字列に変換されます。 "そして、この出力と内部表現を区別する必要があります。必要な標準への参照を提供してください。スタックアドレスはヒープアドレスより大きくてはいけません(または、スタックまたはヒープの必要条件があります)。 – Olaf

+0

"スタックとヒープの割り当てが同じメモリブロックで行われた場合(現代のOSのように私はどこかでこれを読んだことがある)" - 不明瞭なサイトが書いているものはすべて信じられません。それは意味をなさない。あなたは明確にするために著者に尋ねるべきです。 – Olaf

答えて

1

あなたがUbuntuを実行しているとすれば、私はあなたがx86またはx86-64プラットフォームで動作していると仮定しています。それが本当だと仮定すると、あなたのプログラムのレイアウトは次のようになります。

   +-----------------------------+ 
High Address: | Command-line arguments | 
       | and environment variables | 
       +-----------------------------+ 
       |   Stack   | 
       |    |    | 
       |    V    | 
       |        | 
       |   ^   | 
       |    |    | 
       |   Heap    | 
       +-----------------------------+ 
       |  Uninitialized Data  | 
       +-----------------------------+ 
       |  Initialized Data  | 
       +-----------------------------+ 
       |  Program Text   | 
Low Address: |  (machine code)  | 
       +-----------------------------+ 

スタックが高いのアドレスで始まり、ヒープがかなり低いアドレスで始まり、上向きに「成長する一方で、(減少アドレスに向けて)「下向き」に成長"(住所の増加に向かって)。 %p変換指定子は、アドレス値に先行ゼロを表示していません。それがなかった場合は、あなたのアドレスは、先頭にゼロが表示されていないだけということですが、両方のアドレスが実際には同じ長さである

0x0000000001ea2010: heap address 
0x00007ffda62cb3c0: stack address 

ようになります。

+0

私はあなたが伝えようとしていることを理解しました。はい、長さは先行ゼロを許可するのと同じです。 – Parth

2

64ビットアドレスで作業しているようです。すなわち、まで、の16進数の16文字で表示されます。すべてのアドレスを16文字に達するように左側にゼロで埋めなければなりません。

0x0000000001ea2010: heap address 
0x00007ffda62cb3c0: stack address 

ヒープとスタックは、同じ仮想2^64バイト空間に存在します。

0

標準はありません。

しかし、典型的には、ヒープは上向きに成長し、スタックは下向きに成長する。したがって、論理的には、開始点では、ヒープのサイズは小さくなりますが、スタックのサイズは大きくなります。

このような実装が存在するのは、静的なメモリと動的なメモリのオーバーラップが少ないためです。

上記の仮想アドレスと物理アドレスのうちの誰か。コンテキスト上、プロセス内のすべてのメモリは仮想アドレスであるため、BUDDYアルゴリズムを説明しようとすると、最高で冗長であり、最悪では無関係です。

-1

あなたは長い通りに住んでいると想像してください。あなたは通りの南端に住んでいます。家の住所は1、2、3です。

道路が北に1マイル走っているとします。道路の北端には998,999,1000番地があると想像してください。

これまでのところ、北と南の端だけが開発されているとします。 20番地から990番地までは未開発の空き地だけです。

しかし、通りの端にはたくさんのアクティビティがあります。新しいバイヤーは20から30のロットを購入し、それらの上に家を建てる。

一方、通りの北端にはそれほど多くの活動はありません。 989と990がたくさん売られているようで、何かがそこに建設されているようです。

したがって、未開発のロットの「プール」はどこにありますか?通りの北端または南端にありますか?

これまでのところ、ストリートの北端(990-1000)よりも、ストリートの南端(1-20、成長)に住宅が増えています。今のところ、通りの南端での成長はより速い。 (南端に建設中の10ロット、北側で2ロット)

道路の北端にある住所は、それよりも大きい(9桁または4桁で始まる3桁)。南(2桁)。これは何を意味するのでしょうか? (答え:実際には何も意味しません)

2

printfの書式文字列は、先行ゼロをスキップするように指定しています。これがデフォルトです。 %016p、%016x、または%016X(大文字の16進文字が必要な場合)のように、印刷されたアドレスの長さを指定する必要があります。

正しく仮定すると、すべてのポインタは同じ長さでなければなりません。

関連する問題