スタックとヒープがどのように成長するかを確認するために、malloced メモリとローカル変数をいじっていました。私の理解では、ヒープは上向きに成長し、スタックは下向きに成長します。malloc を使用して割り当てられたメモリはすべてヒープに割り当てられ、ローカル変数は関数内のスタックに割り当てられます。
次のプログラムでは:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 999999999
void tot(){
static int c =0;
int k;
c++;
int *pp = malloc(sizeof(int) * SIZE);
if(pp==NULL){
fprintf(stderr,"NO memory allocated after call : %d\n",c);
return;
}
printf("%p %d %p\n",&k,c,pp);
tot();
}
int main(int argc, char *argv[]){
int k;
int *pp = malloc(sizeof(int) * 99999);
if(pp ==NULL){
fprintf(stderr,"No memory allocated\n");
return;
}
printf("%p %p\n",&k,pp);
tot();
return 0;
}
関数 tot() に 4 バイトのローカル変数を 1 つ作成し、int* 型のポインター変数を 1 つ作成しました。これにより、各呼び出しの合計スタック サイズが 4 バイトよりわずかに大きくなります。また、malloc を使用してメモリを割り当て、割り当てられたメモリをローカル ポインタ変数に割り当てました。この malloced メモリはヒープに割り当てられるため、スタック サイズは 4 バイトをわずかに超えるはずですが、上記のプログラムで観察したところ、スタック サイズが大幅に増加しています。その大量の計算を行った後、スタック フレームには、各関数呼び出しで作成された割り当てられたメモリが含まれていることがわかりました。
線を抜いても
int *pp = (int*)malloc(sizeof(int) * SIZE);
これは、各関数呼び出しでこの大きなメモリを割り当てる責任があり、スタック フレームのサイズを ~4 バイトに減らします。これは完全に問題ありません。
ただし、スタック フレームは両方の状況で下向きに成長しています。
なぜ私はそのような出力を得ているのですか。動的メモリがヒープに割り当てられているという私の考えは間違っていますか。malloced メモリがスタック フレームのサイズを増やしているのはなぜですか?
EDIT:私はまた、1つのスタックフレームに割り当てられたメモリへのポインタを他の関数呼び出し(別のスタックフレーム)に渡すことによって、他のスタックフレームの1つのスタックフレームに割り当てられたメモリにアクセスしようとしました。コンパイラが malloc を alloca に内部的に変換していないかどうかを確認するための他の呼び出し (これが大きなスタック フレームの原因である可能性があります) が、違いはありませんでした。結果はまだ同じです。