質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

5372閲覧

MacでのC言語の変数の宣言の順番と変数のメモリ上のアドレス

akamakku

総合スコア191

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/02/08 14:26

編集2017/02/08 14:30

セキュリティの勉強をしている学生です。
いままではどのようにコードを書くかということしか考えていませんでしたが、オーバーフローなどの実践をするためにメモリを意識してC言語を書いています。

ひとまず書いたコードから

C

1#include <stdio.h> 2 3int main(){ 4 int a; 5 int buffer[10]; 6 7 printf("a : %p\n", &a); 8 printf("buffer : %p\n", buffer); 9 10 return 0; 11}

bash

1$ ./a.out 2a : 0x7fff57f35a08 3buffer : 0x7fff57f35a10

C

1#include <stdio.h> 2 3int main(){ 4 int buffer[10]; 5 int b; 6 7 printf("b : %p\n", &b); 8 printf("buffer : %p\n", buffer); 9 10 return 0; 11}

bash

1$ ./a.out 2b : 0x7fff58186a08 3buffer : 0x7fff58186a10

変数の宣言の順番を変えてそのアドレスを出力するだけのプログラムです。

自分が読んだサイトによると、ローカル変数はスタックに積まれるので、宣言の順番によってそれらのアドレスが変わるとなっており、そう理解しました。

が、Macで上記の2コードの出力を見ると、どちらも順番がおなじになっています。
ちなみにVagrantのCentOS7では、予想通り2つのコードで順番が変わりました。

どちらのOSでもgccを使いました。
コンパイル時はどちらもオプションなしです。

なぜMacではうまくいかないんでしょうか?
最適化のようなものが働いているんでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

最適化が働かなくても、どう割り当てられるかはコンパイラに依存します。初歩的な最適化でも条件が揃えば(レジスタで済むので)そもそもスタックに割り当てられないこともあります。

もしそのサイトが「宣言された順番に」と明言しているなら間違いです。宣言された順番に割り当てられることが保証されているのはたぶん構造体メンバだけです。

セキュリティの世界では攻撃者は移植性ではなくて、特定のターゲットを決めるでしょうから、そこはあまり重要ではないのでしょう。ターゲットがVisualStudioでビルドされているのなら、それにあわせればいいのです。

ところで64bitのMacでは、そのサイトの後半にある「戻りアドレスの書き換え」はうまくいきません。こうところも、自身の環境にあわせて調整する必要があります。メモリを意識してしていれば、修正は難しくはないと思います。

投稿2017/02/08 14:59

sharow

総合スコア1149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akamakku

2017/02/08 15:08

なるほど 簡単に考えすぎていました。 ありがとうございました!
guest

0

ベストアンサー

いくつかあります。

  • 通常、macOSのgccコマンドはGCCではありません。ClangのGCC互換コマンドで、実際はLLVMを使用します。gcc -vで確認すると"Apple LLVM version 8.0.0 (clang-800.0.42.1)"とバージョン情報が出るはずです。

macOSでGCCを使う場合は、Homebrew等で別途インストールする必要があります。その場合でも、コマンドはgcc-6等別になります。

  • オプション指定無しは最適化無しという意味ではありません。本当に最適化を無しにするには-O0などを付ける必要があります。
  • スタックにどのように詰まれるかは最適化によって変わる場合があります。場合によってはスタックに詰まれない(変数自体が無くなっている、レジスタしか使わない)場合もあります。
  • Clangは一度中間コードを生成し、LLVMでバイナリコードを生成します。デバッグ等に影響が無い範囲でLLVMが生成するバイナリがどのようにスタックに詰まれるのかを指定する方法はありません。-O0は最適化無しを意味しますが、その意味は、最も早くコンパイル出来て、最も多くデバッグできることしか意味しません。

投稿2017/02/08 20:57

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

akamakku

2017/02/09 00:48

いろいろ認識が間違っていたみたいです。 とりあえず最適化なしの-O0オプションをつけて実行してみましたが、結果は同じものでした。 ここで質問なのですが、 もし、スタックを使わずにレジスタで済んでしまっている場合、&[変数]で取得したアドレスは何のアドレス何でしょうか?
otn

2017/02/09 02:37

変数のアドレスを取って、それをちゃんと使っている場合は、レジスタ(だけ)でなくメモリ領域に割り当てられると思います。
raccy

2017/02/09 09:27

> とりあえず最適化なしの-O0オプションをつけて実行してみましたが、結果は同じものでした。 本当にGCCですか?Macの`gcc`コマンドはGCCではありませんよ。 なお、Clangですと中間言語を作成するためなのか、スタックの積み方と最適化は関係無いようです。(LLVMの文献まで漁っていないので、細かい動作まではわかりません) > スタックを使わずにレジスタで済んでしまっている場合 あくまでも詰まれない「場合がある」というだけです。otnさんの言うとおり、取得が必要な場合であれば、逆にレジスタだけで済まそうとすることが抑止されます。変数がどのように宣言されるかだけで無く、どのように使用するかによって、最適化によりスタックやレジスタの使い方などは常に変化すると思ってください。
akamakku

2017/02/11 06:31

本物のGCCをインストールしてやってみたらうまくいきました。 勉強になりました ありがとうございました!
guest

0

コンパイラによって違うというのは他の方の回答の通りですが、
メモリにはバウンダリ(語境界)というのがあるので、バウンダリに関係ないchar配列は後ろのほうに割り当てられたのだと思います。

投稿2017/02/09 02:39

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C言語は高級言語なので、コンパイルした後の機械語をみないと細かい部分はわかりません。

ちなみに「C言語ではローカル変数がスタックに積まれる」というのは必ずではありません。「その傾向が強い」だけで仕様上定められているわけではありません。そもそもスタックを持っていないコンピュータもあります。

投稿2017/02/08 16:19

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問