ページ 1 / 1
スタックと配列の方向?
Posted: 2010年8月21日(土) 02:00
by たざき
void hoge(void)
{
int i = 10;
int j = 100;
int *array = &i;
// array[0] == 10
// array[1] == 100
}
のような書き方は正しいのでしょうか?
とりあえずx86+Linux+gccでは動くのですが、一般的な書き方なのかどうかと、
他の環境でも動くことが期待できるのかが知りたいです。
Re:スタックと配列の方向?
Posted: 2010年8月21日(土) 08:26
by box
コメントアウトしてある2行はないものとして考えるのと、
arrayにiのアドレスを代入した後で使っていない点はさておくとして、
書き方そのものは正しいです。
ところで、タイトルとどういう関係があるのですか?
Re:スタックと配列の方向?
Posted: 2010年8月21日(土) 09:36
by Mist
> ところで、タイトルとどういう関係があるのですか?
コードのように連続してスタック変数を宣言した場合、コメントアウトされている行のような結果となる(連続して宣言した変数が連続したアドレスに配置されている)ことが全ての環境で大丈夫かを知りたいということだと思いますよ。
で、私の回答ですがC言語でメモリ上に変数をどのように確保するかを規定しているわけではないので、GCCで動作するのも偶然と考えるのがよいかと思います。
Re:スタックと配列の方向?
Posted: 2010年8月21日(土) 09:38
by toyo
array[1]が j と同じになるかという意味でしょうか
それならVisualC++ではだめでした
宣言順にはスタックに積まれませんしReleaseとDebugでもスタックへの積まれ方が違っています
Re:スタックと配列の方向?
Posted: 2010年8月21日(土) 09:42
by box
> int i = 10;
> int j = 100;
> int *array = &i;
> // array[0] == 10
> // array[1] == 100
コメントアウトしてある1行目は正しいです。
それに対して、array[1]に相当する領域を確保していないため、
2行目は正しくないです。
仮に、array[1]に相当する領域を確保してあったとしても、
array = &i;
「だけ」でarray[1]にjの値(100)が入る保証はどこにもありません。

Re:スタックと配列の方向?
Posted: 2010年8月21日(土) 09:48
by たざき
(質問が不明瞭で申し訳ありませんでした。)
本来の意味としては、
スタックに積んだ自動変数に配列ごしにアクセスできるのかということでした。
スタックが伸びる向き(アドレスが増えるか減るか)と配列の添え字でアドレスを増やすのが、
違う向きだったら動かないだろうなあ、と思ってたんです。
そしてそれが環境によって変わってくるのか、ということでした。
とここで、改めて実験してみたんです。
#include <stdio.h>
int main(void)
{
int i = 10;
int j = 100;
int *array = &i;
printf("a0: %d\n", array[0]);
printf("a1: %d\n", array[1]);
}
結果
a0: 10
a1: -1076930628
あれっ?
ならば
#include <stdio.h>
int main(void)
{
int i = 10;
int j = 100;
int *array = &j;
printf("a0: %d\n", array[0]);
printf("a1: %d\n", array[1]);
}
結果
a0: 100
a1: 10
やっぱりそんなことできないんですね。
昨日の時点ではちゃんと動いた気がしたんですけど……。
というわけでおおよそ疑問は解けました。
スタックの伸びる向きに依存して、環境によって動くどうかは不明と。
舌足らずの上に、不十分な質問で、本当にすいませんでした。
質問に答えてくれた方ありがとうございました。
(とプレビューを押した時点でさらに多くのコメントが……、
完全に解決!です。サンクスでした。)
Re:スタックと配列の方向?
Posted: 2010年8月21日(土) 11:52
by softya
付け加えるなら最適化によって、ローカル変数がスタック上に存在しない(CPUのレジスタ上だけ)って事も考えられます。変数も宣言順にスタックに確保しなければイケない規約も存在しません。
なので、出来たとしたらほんの偶然です。