Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
C言語を知らない人がびっくりしそうなC言語の特徴 ~変数定義編~
Satoru Takeuchi
PRO
January 17, 2023
Technology
1
51
C言語を知らない人がびっくりしそうなC言語の特徴 ~変数定義編~
以下動画のテキストです。
https://youtu.be/g7ZcZTkOAl4
Satoru Takeuchi
PRO
January 17, 2023
Tweet
Share
More Decks by Satoru Takeuchi
See All by Satoru Takeuchi
仮想記憶 ~確認編~
sat
PRO
0
25
仮想記憶 ~概念編~
sat
PRO
2
39
ゆく年くる年2022
sat
PRO
0
170
Capacity-aware Dynamic Volume Provisioning For LVM-based Local Storage
sat
PRO
2
190
Rook/Cephストレージシステムを開発しながらupstream OSSに成果を還元してきた取り組み
sat
PRO
2
490
俺とサブウーファー
sat
PRO
0
150
Revealing BlueStore Corruption Bugs in Containerized Ceph Clusters
sat
PRO
1
120
『Linuxのしくみ』増補改訂版発売記念イベント ~ Linuxのしくみのしくみ ~
sat
PRO
2
680
GitHub-hosted runnerでそこまでやるの!?Rookの場合
sat
PRO
0
500
Other Decks in Technology
See All in Technology
OCIコンテナサービス関連の技術詳細 /oke-ocir-details
oracle4engineer
PRO
0
770
OCI DevOps 概要 / OCI DevOps overview
oracle4engineer
PRO
0
490
NGINXENG JP#2 - 4-NGINX-エンジニアリング勉強会
hiropo20
0
100
創業1年目のスタートアップでAWSコストを抑えるために取り組んでいること / How to Keep AWS Costs Down at a Startup
yuj1osm
3
2.1k
Oktaの管理者権限を適切に移譲してみた
shimosyan
2
260
03_ユーザビリティテスト
kouzoukaikaku
0
330
日経電子版だけじゃない! 日経の新規Webメディアの開発 - NIKKEI Tech Talk #3
sztm
0
280
WebLogic Server for OCI 概要
oracle4engineer
PRO
3
870
金属加工屋の営業マンがSTマイクロで・・・
usashirou
0
160
OPENLOGI Company Profile
hr01
0
12k
ラズパイとGASで加湿器の消し忘れをLINEでリマインド&操作
minako__ph
0
140
データベースの発表には RDBMS 以外もありますよ
maroon1st
0
230
Featured
See All Featured
Product Roadmaps are Hard
iamctodd
38
7.7k
Documentation Writing (for coders)
carmenintech
51
2.9k
Building Adaptive Systems
keathley
27
1.3k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
351
21k
How GitHub Uses GitHub to Build GitHub
holman
465
280k
Art, The Web, and Tiny UX
lynnandtonic
284
18k
Put a Button on it: Removing Barriers to Going Fast.
kastner
56
2.5k
The Straight Up "How To Draw Better" Workshop
denniskardys
226
130k
4 Signs Your Business is Dying
shpigford
171
20k
We Have a Design System, Now What?
morganepeng
37
5.9k
The Art of Programming - Codeland 2020
erikaheidi
35
11k
Building a Modern Day E-commerce SEO Strategy
aleyda
6
4.5k
Transcript
C言語を知らない人がびっくりしそうな C言語の特徴 ~変数定義編~ Jan. 17th, 2023 Satoru Takeuchi twitter: satoru_takeuchi
はじめに • 想定聴衆 ◦ 「C言語は聞いたことはあるがどんなものか知らない」という人 ◦ メモリ管理を自分でしなくていいプログラミング言語を使っている人 ▪ ここ十数年で生まれた言語はだいたいそう •
はなすこと ◦ 想定聴衆に向けてC言語の特徴を紹介 ◦ 今回は変数定義について • 環境 ◦ OS: Ubuntu 20.04/x86_64 ◦ gcc: Ubuntu 9.4.0-1ubuntu1~20.04.1
変数定義時の振る舞い • ほとんどの人が思い浮かべる挙動 ◦ デフォルトの値に初期化される • C言語の挙動 ◦ 変数を定義するだけでは何が入っているかは未定義 ◦
別の関数を呼び出したときに定義した別のデータの残骸がのこっているかも
サンプルコード1 1. main()の中で変数iを定義 2. iの値を表示 • 実行結果はどうなる? ◦ 直観的には0を表示 #include
<stdio.h> int main(void) { int i; printf("%d\n", i); }
サンプルコード1の実行結果 • 0が表示された ◦ C言語としてiを0に初期化しているのではなく、「たまたまこうなった」だけ #include <stdio.h> int main(void) {
int i; printf("%d\n", i); }
サンプルコード2 1. foo()を呼ぶ 1.1. 変数iを定義して100で初期化 2. bar()を呼ぶ 2.1. 変数iを定義して初期化はしない 2.2.
iの値を表示 • 実行結果はどうなる? ◦ 現代的な言語なら0になりそう #include <stdio.h> void foo(void) { int i = 100; } void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); }
サンプルコード2の実行結果 • 初期化してないbar()内の変数iの値が100 #include <stdio.h> void foo(void) { int i
= 100; } void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); }
挙動の説明 1. 前提知識となるスタックの説明 2. サンプルコード2の挙動の説明
スタックとは • プログラムの関数呼び出しの流れとローカル変数を管理するしくみ • データ構造はスタック(であるがゆえにスタックという名前がついている • 関数を呼び出すたびにローカル変数を含むスタックフレームというものをpushする というイメージ • 一般にメモリアドレスの大きな方向から小さな方向に伸びる
スタックの説明(1/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス 📝 戻りアドレスとか フレームポインタとか
スタックの説明(2/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス fooのいろいろ fooのiの値(10) push
スタックの説明(3/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス fooのいろいろ fooのiの値(10) barのいろいろ barのiの値(100) push
スタックの説明(3/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス fooのいろいろ fooのiの値(10) ゴミ ゴミ(100) pop
スタックの説明(3/4) #include <stdio.h> void bar() { int i = 100;
} void foo() { int i = 10; bar(); } void main() { int i = 1; foo(); } メモリ スタック … … いろいろ mainのiの値(1) 0 大きい アドレス ゴミ ゴミ(10) ゴミ ゴミ(100) pop
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス fooのいろいろ fooのiの値(100) push
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス ゴミ ゴミ(100) pop
サンプルコード2の挙動の説明 #include <stdio.h> void foo(void) { int i = 100;
} void bar(void) { int i; printf("%d\n", i); } int main(void) { foo(); bar(); } メモリ スタック … … いろいろ 0 大きい アドレス barのいろいろ barのi(100) push 初期化していないので fooのゴミが残っている!
まとめ • C言語では変数定義時に初期化しないと、どんな値が入っているかは未定義 ◦ 現代的な言語のように必ず初期化するより高速だが危なっかしい ◦ 変なデータが見えてしまってセキュリティホールになることも • あくまで「未定義」なので、環境によって結果は異なる