C言語で、グローバル変数とローカル変数と動的メモリ(malloc)の違い言える?
■ このスレッドは過去ログ倉庫に格納されています
マロックキャストサイズオブうんたらが嫌いすぎてパイソンに逃げた printf("C言語で、グローバル変数とローカル変数と動的メモリ(malloc)の違い言える?") 最近のRust良いぞとか言ってる若者はこの辺を理解してるんだろうか、 マロックとかあったなぁ並列処理とかでも使った気がする
もう全部忘れたけど
ライブラリが全部やってくれるよ(´・ω・`) C言語での変数は、宣言された位置によって、グローバル変数、ローカル変数、静的変数の3種類に分類される。
**グローバル変数**は、関数の外部で宣言された変数です。プログラムのどこからでも参照することができ、プログラムの終了までメモリに確保されたままになる。
**ローカル変数**は、関数の内部で宣言された変数。関数が呼び出されている間だけメモリに確保され、関数が終了するとメモリから解放される。
**静的変数**は、関数の内部で宣言された変数だが、`static`キーワードが付与された変数。ローカル変数と同じように、関数が呼び出されている間だけメモリに確保されるが、プログラムの終了までメモリから解放されない。
**動的メモリ(malloc)**は、プログラム実行中にメモリを動的に確保する機能。グローバル変数、ローカル変数、静的変数は、プログラムのコンパイル時にメモリの割り当てが行われるが、動的メモリはプログラム実行時に必要に応じてメモリを割り当てる。
グローバル変数は、プログラム全体で参照可能なため、変数の値を他の関数から参照したり、関数間でデータを共有したりする際に便利。ただし、グローバル変数はプログラム全体でメモリを占有するため、メモリ使用量が大きくなってしまうというデメリットもある。
ローカル変数は、関数内でのみ参照可能なため、メモリ使用量を抑えることができる。また、関数が終了するとメモリから解放されるため、メモリリークが発生するリスクも低くなる。ただし、関数間でデータを共有したり、他の関数から参照したりする際には、グローバル変数よりも複雑な処理が必要になる。
静的変数は、ローカル変数と同様に、関数内でのみ参照可能。ただし、関数が終了してもメモリから解放されず、プログラムの終了までメモリに確保されたままになる。そのため、グローバル変数と同様に、メモリ使用量を大きくしてしまうというデメリットがある。
動的メモリは、プログラム実行時に必要なメモリの量を動的に割り当てることができるため、メモリ使用量を最適化することができる。ただし、メモリを解放するのを忘れるとメモリリークが発生するリスクがあるため、注意が必要。 グローバル変数(Global Variables):
グローバル変数は、関数の外部で宣言された変数です。つまり、どの関数からでもアクセスできます。
プログラム全体で有効なスコープを持ち、プログラムが実行される間ずっと存在します。
プログラムのあちこちで使用できるため、慎重に使用する必要があります。グローバル変数の過度の使用は、プログラムの複雑性や保守性の問題を引き起こす可能性があります。
c
int globalVariable; // グローバル変数
ローカル変数(Local Variables):
ローカル変数は、関数内で宣言された変数です。その関数内でのみアクセス可能です。
関数が呼び出されると変数が作成され、関数の実行が終了すると変数も破棄されます。これを「スタック上のメモリ」を使用しています。
ローカル変数は他の関数からは直接アクセスできません。
c
void exampleFunction() {
int localVar; // ローカル変数
// localVarを使用する処理
}
動的メモリ割り当て(malloc関数):
動的メモリ割り当ては、実行時にメモリを動的に確保するための仕組みです。malloc関数を使用します。
動的に確保されたメモリは、明示的に解放するまで存在し続けます。これにより、プログラムの実行中に必要なだけのメモリを確保できます。
動的メモリは通常ポインタを介して操作され、ポインタが指す先のメモリブロックが動的に確保されます。
c
int *dynamicVar = (int *)malloc(sizeof(int)); // 動的メモリ割り当て
// dynamicVarを使用する処理
free(dynamicVar); // メモリ解放
これらの変数の違いを理解しておくことは、効果的なプログラミングとメモリ管理に重要です。グローバル変数は慎重に使用し、ローカル変数や動的メモリ割り当てを適切に利用することで、プログラムの構造と効率性を向上させることができます。 >>8
mallocが理解できてなくてオブジェクト指向が理解できるのだろうか… >>12
C++でオブジェクトを宣言すると動的メモリが使われるよ
この思想はその他の言語でも変わらんはず >>11
chatGPTくんはこの問題の本質を理解してない。 「何もかも違う」←これがマジで一番適切な答えなんよな
この違いがわからんと中級者とは言えんよ こういうコードを書いてコンパイルして実行した時に、一番最初のメモリの状態がわかるかな?
int a = 11;
int main () {
int b = 22;
return 0;
} ここで解放されます~とかなんかぼやっと聞いてたな
今のスペックだとそんなん気にしなくていいしな グローバル変数は静的メモリに、ローカル変数はスタックに、mallocはヒープに、みたいな話? >>17
指定してないから分かるはずねーだろハゲって思うけどランダム割り当てじゃないの? * グローバル変数は、プログラムの開始時にメモリに確保され、値は宣言時に指定された値が格納される。
* ローカル変数は、関数が呼び出されている間だけメモリに確保され、値は初期化されていなければ 0 が格納される。
**具体的な例**
```
int a = 11;
int main () {
int b = 22;
return 0;
}
```
このコードをコンパイルして実行すると、以下のようになる。
* グローバル変数 `a` は、1バイトのメモリに確保され、値は 11 が格納される。
* ローカル変数 `b` は、1バイトのメモリに確保され、値は 0 が格納される。 >>21
おまえSiki使いか
ソースコード出てきたw >>22
みんな分からないんだな
それじゃわざわざC使う意味ないじゃん >>20
プロセスが実行されるとカーネルはそのプロセス専用の仮想メモリを用意して、プログラムのバイナリをその仮想メモリ上に乗っけるのよ
では仮想メモリが実行初期にどんな感じかイメージできる? >>22
次のプログラムをコンパイルして実行すると、`a` の値はどうなるか?
#include <stdio.h>
int a = 10;
int main() {
static int a = 20;
printf("%d\n", a);
return 0;
} >>24
わからないらしいよ
最近の人はグローバル変数とローカル変数の違いさえ理解してないようだからね
このレベルでRust良いぞとか言ってるからなぁ >>29
正解!
簡単すぎたか
次のプログラムをコンパイルして実行すると、どのようなメモリリークが発生する可能性があるか?
#include <stdio.h>
void foo() {
char *p = malloc(1024);
// ここに何か処理を記述する
free(p);
}
int main() {
while (true) {
foo();
}
return 0;
} >>30
ヒープとスタックがぶつかるのか?
わからん >>31
普通の言語でも使うじゃん
この辺わからんとオブジェクト指向は理解できてないはず >>32
次のプログラムをコンパイルして実行すると、どのような結果になるか?
#include <stdio.h>
int main() {
int a = 10;
int *p = &a;
int **q = &p;
printf("%d\n", **q);
return 0;
} >>30
フリーされたメモリはマロックできないからいずれマロックできなくなるとか? >>33
大凡認識はあってる
foo() で動的メモリを割り当てているが、そのメモリを解放する前に、関数 foo() が終了してしまう可能性がある。
簡単すぎるか >>38
正解!
俺程度が考えた問題じゃ駄目だなw
次のプログラムをコンパイルして実行すると、どのような結果になるか?
#include <stdio.h>
int main() {
int a[10];
int *p = a;
p += 10;
printf("%d\n", *p);
return 0;
} >>40
一個飛び出してね?未定義動作かな
多分ゼロ >>43
じゃあさ、これのmainは何を返すでしょうか?
int func(int x) {
int y = 22;
int a[] = {};
return a[1] + a[2];
}
int main() {
return func(11);
} >>46
スタックをよく考えてみて
スタックにはx,yが順番に積まれるはず >>47
まあそうなんだけど、結構スタックの勉強になるよね
ちなみに俺の手元のMacのclangの-O0は33を返した >>48
* 関数 `func()` は、配列 `a` の要素 `a[1]` と `a[2]` の合計を返すが、配列 `a` は空の配列であるため、未定義の値を返す。
* そのため、main() 関数も未定義の値を返す????
だめだわからんわ >>51
ローカル変数は宣言するとメモリのスタック領域に順番に積まれてくのよ。
だから配列aの前には変数x,yが順番に並んでるってことだよ >>50
まあコンパイラの仕様によるけどね。
手元のArm64のMacでは33返したわ
x86_64のgcc -O0は未定義だったわ >>53
main() 関数から関数 `func()` を呼び出した後、スタックは
スタック領域
変数 x
変数 y
変数 a
となるよね
関数 `func()` が `a[1] + a[2]` を計算しようとすると、配列 `a` の要素 `a[1]` と `a[2]` が定義されていないため、未定義の値を返すのじゃなくて?
自動的にスタックされるの? わーかったよ。
じゃあx86に限定するよ
そして問題文も以下のように訂正します!
これで満足か?
int func(int x, int y) {
int a[] = {};
return a[1] + a[2];
}
int main() {
return func(11, 22);
} >>57
最初っからそうしとけやクズ
そういうところだろカス >>59
x86ってレジスタ渡しだっけ?
スタックで渡してたような >>56
a[1]は隣のメモリに入っている値を取り出すから11が取り出されるじゃん うん
x86はスタック渡しだわ
x64はレジスタ渡しだけど ■ このスレッドは過去ログ倉庫に格納されています