プロが教える店舗&オフィスのセキュリティ対策術

今私はC言語を勉強中なのですが、その中でサイズ指定のない配列について分からないことが有ります。
参考書では、サイズ指定のない配列の利点は、「配列の次元を変更せずにテーブルを長くしたり短くしたりできること」とありました。
そこで私は、実際に下記のような、参考書に載っていたサイズ指定のない2次元配列を実際に長く出来るか試してみたのですが、コンパイルするとエラーが起こり、正しく表示されませんでした。
(元の実行結果:1 2 3 4 5 6 7 8 9)
(私の予想した変更後の実行結果:1 2 3 4 5 6 7 8 9 11 12 13 21 22 23 31 32 33)
しかし、どこが悪いのかが分かりません。どこを変更すべきかどなたか教えていただけないでしょうか?

<元の配列>
int str[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

<str[][3]を利用したソース>
#include <stdio.h>

int main(void)
{
int i, j;
int str[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

str[3][0] = 11;
str[3][1] = 12;
str[3][2] = 13;
str[4][0] = 21;
str[4][1] = 22;
str[4][2] = 23;
str[5][0] = 31;
str[5][1] = 32;
str[5][2] = 33;

for(i = 0; i < 6; i++)
for(j = 0; j < 3; j++)
printf("%d ", str[i][j]);

return 0;
}

A 回答 (1件)

>参考書では、サイズ指定のない配列の利点は、「配列の次元を変更せずにテーブルを長くしたり短くしたりできること」とありました。



「コンパイルの時点でコンパイラが自動計算してくれる」というだけです。
決して動的にサイズが変更できるワケではありません。

>int str[][3] = {
>{1, 2, 3},
>{4, 5, 6},
>{7, 8, 9}
>};

とりあえず、str[3][3]と書いたのと同義になります。
が、str[4][3]とか、str[1][3]とかにしたい場合に、添え字の数字を書き換えるのを忘れると問題が発生する場合があります。
# まあ、添え字より多ければコンパイルエラー、添え字より少なければメモリの無駄遣いになる程度ですが。
機能拡張とかしたりした時に、サイズが増える(減る)場合があります。
が、添え字の値まで修正し忘れる。ということはたまに発生しますので、コンパイラが自動計算してくれているだけです。
# 少なければコンパイルエラーで判明しますが、多かった場合のメモリの無駄はエラーにならないので判りません。

というわけで…
>int str[][3] = {
>{1, 2, 3},
>{4, 5, 6},
>{7, 8, 9}
>};
としておいて、
>str[3][0] = 11;
だの実行すれば、バッファオーバーランを引き起こし、どこか破壊して吹っ飛びます。

>どこを変更すべきかどなたか教えていただけないでしょうか?

動的確保なりに変更しないと無理です。
# C++のvectorだったら…よろしくやってくれるかも知れません。(動的確保をラップしてくれている。とも言えますが)
    • good
    • 0
この回答へのお礼

なるほど!
そういうことだったんですね。
分かりやすかったです、ありがとうございます(^^)

お礼日時:2015/03/17 17:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!