X



C言語で、グローバル変数とローカル変数と動的メモリ(malloc)の違い言える?
■ このスレッドは過去ログ倉庫に格納されています
0001以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:05:48.485ID:O27KXdknr
これが言えたらプログラミング中級者だぞ
0002以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:07:01.168ID:QogkUKFf0
マロックキャストサイズオブうんたらが嫌いすぎてパイソンに逃げた
0003以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:07:07.722ID:9yXNMMNn0
初級だぞ
0004以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:07:08.579ID:e7EIpRaf0
printf("C言語で、グローバル変数とローカル変数と動的メモリ(malloc)の違い言える?")
0006以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:08:17.246ID:O27KXdknr
>>5
理解してるようだな
君は中級者
0007以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:09:23.913ID:O27KXdknr
最近のRust良いぞとか言ってる若者はこの辺を理解してるんだろうか、
0008以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:09:37.857ID:OHoeBeMr0
マロックとかあったなぁ並列処理とかでも使った気がする
もう全部忘れたけど
ライブラリが全部やってくれるよ(´・ω・`)
0009以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:09:48.115ID:JASVCTlI0
言えるよ
じゃ俺はここで落ちます
0010以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:10:27.678ID:vaFRmexz0
C言語での変数は、宣言された位置によって、グローバル変数、ローカル変数、静的変数の3種類に分類される。

**グローバル変数**は、関数の外部で宣言された変数です。プログラムのどこからでも参照することができ、プログラムの終了までメモリに確保されたままになる。

**ローカル変数**は、関数の内部で宣言された変数。関数が呼び出されている間だけメモリに確保され、関数が終了するとメモリから解放される。

**静的変数**は、関数の内部で宣言された変数だが、`static`キーワードが付与された変数。ローカル変数と同じように、関数が呼び出されている間だけメモリに確保されるが、プログラムの終了までメモリから解放されない。

**動的メモリ(malloc)**は、プログラム実行中にメモリを動的に確保する機能。グローバル変数、ローカル変数、静的変数は、プログラムのコンパイル時にメモリの割り当てが行われるが、動的メモリはプログラム実行時に必要に応じてメモリを割り当てる。

グローバル変数は、プログラム全体で参照可能なため、変数の値を他の関数から参照したり、関数間でデータを共有したりする際に便利。ただし、グローバル変数はプログラム全体でメモリを占有するため、メモリ使用量が大きくなってしまうというデメリットもある。

ローカル変数は、関数内でのみ参照可能なため、メモリ使用量を抑えることができる。また、関数が終了するとメモリから解放されるため、メモリリークが発生するリスクも低くなる。ただし、関数間でデータを共有したり、他の関数から参照したりする際には、グローバル変数よりも複雑な処理が必要になる。

静的変数は、ローカル変数と同様に、関数内でのみ参照可能。ただし、関数が終了してもメモリから解放されず、プログラムの終了までメモリに確保されたままになる。そのため、グローバル変数と同様に、メモリ使用量を大きくしてしまうというデメリットがある。

動的メモリは、プログラム実行時に必要なメモリの量を動的に割り当てることができるため、メモリ使用量を最適化することができる。ただし、メモリを解放するのを忘れるとメモリリークが発生するリスクがあるため、注意が必要。
0011以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:10:32.669ID:/kZmbhL00
グローバル変数(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); // メモリ解放

これらの変数の違いを理解しておくことは、効果的なプログラミングとメモリ管理に重要です。グローバル変数は慎重に使用し、ローカル変数や動的メモリ割り当てを適切に利用することで、プログラムの構造と効率性を向上させることができます。
0012以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:10:40.265ID:lr22hnbm0
動的メモリはわからん(知らん)な
0013以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:11:15.683ID:O27KXdknr
>>8
mallocが理解できてなくてオブジェクト指向が理解できるのだろうか…
0014以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:12:19.982ID:O27KXdknr
>>12
C++でオブジェクトを宣言すると動的メモリが使われるよ
この思想はその他の言語でも変わらんはず
0015以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:13:04.643ID:O27KXdknr
>>11
chatGPTくんはこの問題の本質を理解してない。
0016以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:14:04.196ID:O27KXdknr
「何もかも違う」←これがマジで一番適切な答えなんよな
この違いがわからんと中級者とは言えんよ
0017以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:17:29.065ID:O27KXdknr
こういうコードを書いてコンパイルして実行した時に、一番最初のメモリの状態がわかるかな?

int a = 11;

int main () {
int b = 22;
return 0;
}
0018以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:18:42.174ID:OHoeBeMr0
ここで解放されます~とかなんかぼやっと聞いてたな
今のスペックだとそんなん気にしなくていいしな
0019以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:19:14.722ID:y6SHDoJe0
グローバル変数は静的メモリに、ローカル変数はスタックに、mallocはヒープに、みたいな話?
0020以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:19:22.659ID:gxCZN5z00
>>17
指定してないから分かるはずねーだろハゲって思うけどランダム割り当てじゃないの?
0021以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:19:30.305ID:vaFRmexz0
* グローバル変数は、プログラムの開始時にメモリに確保され、値は宣言時に指定された値が格納される。
* ローカル変数は、関数が呼び出されている間だけメモリに確保され、値は初期化されていなければ 0 が格納される。

**具体的な例**

```
int a = 11;

int main () {
int b = 22;
return 0;
}
```

このコードをコンパイルして実行すると、以下のようになる。

* グローバル変数 `a` は、1バイトのメモリに確保され、値は 11 が格納される。
* ローカル変数 `b` は、1バイトのメモリに確保され、値は 0 が格納される。
0022以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:19:37.205ID:O27KXdknr
>>19
理解してるようだな
君は中級者
0023以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:20:38.675ID:OHoeBeMr0
>>21
おまえSiki使いか
ソースコード出てきたw
0024以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:20:46.671ID:y6SHDoJe0
>>22
みんな分からないんだな
それじゃわざわざC使う意味ないじゃん
0025以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:22:30.087ID:O27KXdknr
>>20
プロセスが実行されるとカーネルはそのプロセス専用の仮想メモリを用意して、プログラムのバイナリをその仮想メモリ上に乗っけるのよ
では仮想メモリが実行初期にどんな感じかイメージできる?
0026以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:23:22.097ID:vaFRmexz0
>>22
次のプログラムをコンパイルして実行すると、`a` の値はどうなるか?

#include <stdio.h>

int a = 10;

int main() {
static int a = 20;
printf("%d\n", a);
return 0;
}
0027以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:24:32.792ID:OHoeBeMr0
バイナリだけで読める人って本当に存在するの
0028以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:24:34.781ID:O27KXdknr
>>24
わからないらしいよ
最近の人はグローバル変数とローカル変数の違いさえ理解してないようだからね
このレベルでRust良いぞとか言ってるからなぁ
0029以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:27:16.824ID:O27KXdknr
>>26
20
0030以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:28:36.670ID:vaFRmexz0
>>29
正解!

簡単すぎたか


次のプログラムをコンパイルして実行すると、どのようなメモリリークが発生する可能性があるか?

#include <stdio.h>

void foo() {
char *p = malloc(1024);
// ここに何か処理を記述する
free(p);
}

int main() {
while (true) {
foo();
}
return 0;
}
0031以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:31:06.508ID:YNGvXAzg0
こういうのっていつ使うの?
0032以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:31:53.828ID:LqJpX6s30
上級者ぼく「ポインタ使えば全部同じw」
0033以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:32:28.173ID:fVulArTJr
>>30
ヒープとスタックがぶつかるのか?
わからん
0034以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:33:18.623ID:fVulArTJr
>>31
普通の言語でも使うじゃん
この辺わからんとオブジェクト指向は理解できてないはず
0035以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:33:56.722ID:vaFRmexz0
>>32


次のプログラムをコンパイルして実行すると、どのような結果になるか?

#include <stdio.h>

int main() {
int a = 10;
int *p = &a;
int **q = &p;

printf("%d\n", **q);

return 0;
}
0036以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:35:12.348ID:QogkUKFf0
>>30
フリーされたメモリはマロックできないからいずれマロックできなくなるとか?
0037以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:35:37.743ID:vaFRmexz0
>>33

大凡認識はあってる

foo() で動的メモリを割り当てているが、そのメモリを解放する前に、関数 foo() が終了してしまう可能性がある。

簡単すぎるか
0038以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:37:15.412ID:fVulArTJr
>>35
10じゃね?
0039以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:40:12.428ID:3I8b11gL0
マロック言う奴きらい
0040以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:41:08.102ID:vaFRmexz0
>>38
正解!

俺程度が考えた問題じゃ駄目だなw



次のプログラムをコンパイルして実行すると、どのような結果になるか?

#include <stdio.h>

int main() {
int a[10];
int *p = a;

p += 10;

printf("%d\n", *p);

return 0;
}
0041以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:43:33.477ID:VMxh4xj80
C++のスマートポインタ使えよ
0042以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:44:36.471ID:jC6TtW0Tr
>>40
一個飛び出してね?未定義動作かな
多分ゼロ
0043以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:45:10.012ID:vaFRmexz0
>>42
流石だわ完璧な回答
0044以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:54:36.195ID:8YauGRvgr
>>43
じゃあさ、これのmainは何を返すでしょうか?

int func(int x) {
int y = 22;
int a[] = {};
return a[1] + a[2];
}

int main() {
return func(11);
}
0045以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 00:55:19.289ID:8YauGRvgr
>>43
ちなみに最適化はしないものとする
0046以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:00:25.162ID:vaFRmexz0
>>44
未定義?
undefined
0048以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:03:09.057ID:3L4iGCU9r
>>46
スタックをよく考えてみて
スタックにはx,yが順番に積まれるはず
0049以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:04:21.485ID:3L4iGCU9r
>>47
まあそうなんだけど、結構スタックの勉強になるよね
ちなみに俺の手元のMacのclangの-O0は33を返した
0051以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:06:09.018ID:vaFRmexz0
>>48

* 関数 `func()` は、配列 `a` の要素 `a[1]` と `a[2]` の合計を返すが、配列 `a` は空の配列であるため、未定義の値を返す。
* そのため、main() 関数も未定義の値を返す????

だめだわからんわ
0053以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:10:51.699ID:BEnHAk3Rr
>>51
ローカル変数は宣言するとメモリのスタック領域に順番に積まれてくのよ。
だから配列aの前には変数x,yが順番に並んでるってことだよ
0055以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:13:17.299ID:BEnHAk3Rr
>>50
まあコンパイラの仕様によるけどね。
手元のArm64のMacでは33返したわ
x86_64のgcc -O0は未定義だったわ
0056以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:14:29.490ID:vaFRmexz0
>>53

main() 関数から関数 `func()` を呼び出した後、スタックは

スタック領域

変数 x
変数 y
変数 a

となるよね

関数 `func()` が `a[1] + a[2]` を計算しようとすると、配列 `a` の要素 `a[1]` と `a[2]` が定義されていないため、未定義の値を返すのじゃなくて?
自動的にスタックされるの?
0057以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:16:11.053ID:BEnHAk3Rr
わーかったよ。
じゃあx86に限定するよ
そして問題文も以下のように訂正します!
これで満足か?

int func(int x, int y) {
int a[] = {};
return a[1] + a[2];
}

int main() {
return func(11, 22);
}
0058以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:17:05.813ID:QogkUKFf0
>>57
最初っからそうしとけやクズ
そういうところだろカス
0060以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:18:31.768ID:BEnHAk3Rr
>>59
x86ってレジスタ渡しだっけ?
スタックで渡してたような
0061以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:20:16.996ID:BEnHAk3Rr
>>56
a[1]は隣のメモリに入っている値を取り出すから11が取り出されるじゃん
0062以下、5ちゃんねるからVIPがお送りします
垢版 |
2023/12/18(月) 01:24:21.828ID:BEnHAk3Rr
うん
x86はスタック渡しだわ
x64はレジスタ渡しだけど
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況