アプリ版:「スタンプのみでお礼する」機能のリリースについて

dsPICで配列を使用する際、他の変数もその配列の存在するメモリ領域に配置されてしまいます。
プログラムにはC言語を用いています。環境は「MPLAB C30 v3.31」、「MPLAB LINK30 v3.31」「MPLAB v8.85」です。
状況としてはunsigned char型で要素数320の配列をグローバル宣言します。そしてmain関数やその他の関数内でローカル変数を宣言するとその変数が配列の中に存在することになってしまうというものです。色々試したところ、そのローカル変数をstaticで宣言するとそのような症状は出なくなりました。
この現象には、初期化をする関数内でカウンタとしてローカル変数を宣言し、for文で配列を0でクリアさせようとしたところ、MPLABSIMでデバッグすると永久ループしたことから気づきました。Watchを用いて確認したところ配列の中にそのカウンタ変数が配置されていたため最終的に自分自身を0でクリアしてしまうことで永久ループしてしまうことがわかりました。
なぜこうなるのかよくわかりません。この配列以外にはおおきな領域を必要とする変数は宣言していませんのでData memoryの容量的な問題ではないと思っています。staticで宣言すれば何とかなりますが、これでは無駄なメモリを消費してしまいます。また、絶対アドレス指定をする方法もありますが、「ignoring address attribute applied to automatic 変数名」というwarningがでて結局出来ませんでした。

このような現象を起こさせない様にするため,、確実にメモリを確保するためにはどうすればよいのでしょうか。
この問題のために先に進めず、大変困っております。どうかご教授ください。

もう一つ、変数の生存期間について質問なのですが、ある関数内で宣言したローカル変数をカウンタとして使い、指定の回数だけ他の関数を繰り返し実行する場合、他の関数に飛んだ時もそのローカル変数は確実に生存しているのでしょうか。重ねてお願いします。
不足がございましたら補足しますのでお教え下さい。

A 回答 (5件)

>ある関数内で宣言したローカル変数をカウンタとして使い、


>指定の回数だけ他の関数を繰り返し実行する場合、
>他の関数に飛んだ時もそのローカル変数は確実に生存しているのでしょうか。
要するに
int i;
for (i=0;i < 10; i++){
some_func();
}
ということをやった場合、some_func内の処理を実行中でもiは存在しているか?ということでしょうか?
その意味ではiは存在しています。
ただし、そのiへのポインタを何らかの方法でsome_funcが知ることができなければ、そのiに直接アクセスできません。
some_funcの引数としてiを渡した場合は、関数呼び出し時のiの値が別の変数にコピーされてくるため、その値を変更しても元の値に影響を与えません。つまり
void other_func(int j)
{
j = 10;
}

int j=1;
other_func(j);
printf("%d", j);
という処理では10ではなく1が表示されます。

この回答への補足

tadysさんと重ねて補足させていただきます。
回答ありがとうございました。説明不足でしたが、今回私が試みているのは指定の回数だけ関数を繰り返すというものですので呼び出す関数内でそのカウンタとしての変数を参照することはありません。確認したかったのは他の関数に飛んだ時もその変数は開放されたりせず、存在しているかどうかです。
tadysさんとhitomuraさんとで意見が異なるようなのですがどちらが正しいのでしょうか?

補足日時:2012/07/25 16:25
    • good
    • 0

>何度も失敗しながらも取り組んでいけば得られるものもあると思っているのでこれからも頑張っていくつもりです。



失礼いたしました。向学心に水を指すようなことを言ってしまいました。頑張って習得してください。
    • good
    • 0

関数A から関数B を呼んだ場合, 関数A の中で定義された変数は「関数B からアクセスすることはできないが値は保存される」が正解. #1 の「抜け出した」は「関数が終わったら」って意味じゃないかな.



本題については, とりあえず #3 で指摘されているところを確認するくらいかなぁ. あとは, メモリマップを見て「変数がどこに割り当てられているか調べる」とか.
    • good
    • 0
この回答へのお礼

お礼が遅くなって申し訳ありません。
結局、様々な方法を試しましたが解決できず、諦めて実際のハード(PIC)に書き込んで実行した所、特に問題なく動くことが確認できました。原因はわかりませんが、永久ループも起こっていないですし、ビットのズレなどのエラーも起こっていません。最終的にはMPLABSIM側の問題かと思っています。
ご多忙の所お付き合いくださってありがとうございました。他の回答者様と重ねて御礼申し上げます。

お礼日時:2012/08/03 01:32

PICには詳しくないので、外してたらすみませんが、これは多分文法とかの問題ではないでしょう。


自動変数は、通常、スタックに生成されるものが多いと思います。
リンカでの指定がちゃんと行われているか?
スタートアップ部で、スタックポインタや、スタックセグメントがちゃんと設定されているか?
そういった所を確認してみてはいかがでしょうか?

最後の質問の内容から見ると、いきなり組み込み系の開発は難しいんじゃないでしょうか?

この回答への補足

回答ありがとうございました。おっしゃるとおり私はまだまだ未熟なので勉強が必要だと思っています。最後の質問に関しては今まで当たり前のようにしてきましたが、うまくいっていたのは偶然だったのではないかと思い立ったためです。PICは簡単なことをするのであれば初心者向けでインターネット上に情報がたくさんあるために勉強しています。何度も失敗しながらも取り組んでいけば得られるものもあると思っているのでこれからも頑張っていくつもりです。
ご指摘いただいた部分に関しては改めて確認したいと思います。

補足日時:2012/07/25 16:35
    • good
    • 0

>他の関数に飛んだ時もそのローカル変数は確実に生存しているのでしょうか。


C言語のローカル変数は、その関数の中だけで有効です。
関数から抜けだした時点で死んでいます。
死なないようにするにはstatic宣言をするか、グローバル宣言をするしか方法は有りません。
    • good
    • 0

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