«前の日記(2003年11月16日) 最新 次の日記(2003年11月18日)» 編集

だめだめ日記

ツッコミの内容は検索サイトからの検索やサイトのレーティングに影響します。そのため問題があるキーワードを含むと思われるツッコミについては、当方の判断で削除することがあります。予めご了承ください。 なお、コメントspamと判断されたツッコミは自動的に消去されます。ご容赦ください。
2002|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|05|06|09|10|11|12|
2013|01|02|02|03|08|09|
2014|01|
2015|09|10|11|
2016|01|04|

執筆、翻訳などに関わった書籍類


【改訂新版】Samba [実践]入門

Linux教科書
LPICレベル3 300試験

マスタリング Nginx

実践 パケット解析 第2版

改訂版 Sambaのすべて

アンドキュメンテッド
Microsoftネットワーク

その他の書籍は だめだめ日記のおみせ@本店でどうぞ。



2003年11月17日 [長年日記]

[原稿] 某雑誌2の原稿

やっと提出。

これでひとつクリア。

[だめ] 関数の戻り値

たとえば

int main() {
    int j;
    ...
    j = func();
    ...
}
 
int func() {
    int i;
 
    return i;
}

の場合、iはauto変数だけど、returnの引数のiは、スタックに積まれるので、呼び出し元で変数jに代入する時点で正しい値であることが保証されるわけですよね。一方、これが

int main() {
    char p[10];
    ...
    strcpy(p, func());
    ...
}
 
char *func() {
    char tako[];
    return tako;
}

だった場合、スタックに積まれるのはtakoのポインタだけで、配列の実体は親関数に制御が戻った時点で解放されてしまうので、配列の値は保証できないという理解でよかったんでしたっけ上記のソースっぽいのは説明のために適当に書いてみただけで、このとおりのことをやろうしているわけではないです。念のため

C言語すらできない、いっぱんじんですみませんm(_:_)m

[SYSTEM] monyo.comドメイン更新

すっかり忘れていて、期限3日前ですという督促で危いところ、気づきました。

インターネットショッピング払込依頼票なるものを持ってセブンイレブンで支払い

本日のツッコミ(全12件) [ツッコミを入れる]
_ watayan (2003年11月18日 09:41)

確かレジスタ返しをするコンパイラもあるので「スタックに…」<br>というのは実装の一例ではありますが,動作としてはそんな感じ<br>になると思います(char tako[]="hoge"; とかの場合)。

_ みゃー (2003年11月18日 11:58)

ゲソコーおつかれさまですた(´ー`)ノ

_ monyo (2003年11月18日 12:12)

>「配列の値は保証できない」という理解でよいと思います。 <br>>より厳密に言えば、配列の値だけでなく、tako のポインタ <br>>(アドレス)そのものも無効です。 <br><br>そうすると、<br><br>int func() {<br> i = 1;<br> return i;<br>}<br>みたいなときに、この関数の戻り値も言語仕様として保証されなくなると思ったりしたんですが、結構上記のような関数ってありますよね。<br>というところで、ずっとはまってました > 昨日<br><br>もちろん (3) すれば確実なのはわかってるんですが。<br><br>> 手元の VC++ では int型 の関数の場合、AXレジスタで<br>>渡していますね。<br><br>なるほど、そうすれば安全?ですね。

_ とぴあ (2003年11月18日 12:34)

> i = 1;<br>の場合の i は何型の変数なんでしょ?<br>ポインタ/配列以外(でよかったでしたっけ?)なら普通に値渡しですけれども・・・

_ woods (2003年11月18日 12:37)

アドレスの値(0x100078f0みたいな「数値としての値」)は有効だけど、その先にあるメモリは確保されているとは限らないということで。<br>int f(){int i = 3; return i;}<br>のような場合は「数値としての値」である"3"は有効なのです。

_ nao (2003年11月18日 12:46)

>この関数の戻り値も言語仕様として保証されなくなると思ったりしたんですが、結構上記のような関数ってありますよね。 <br>ポインター変数を返値とした場合は、アドレスが返値として呼び出し元に返ります。<br>この変数は正常に返りますが、そのポインターが示す先の領域が関数内の自動変数なので<br>関数を抜けた後は、不定な値となり問題になります。<br>(実際にはスッタクで実装されるので、上書きされるまで大丈夫だったりします)<br><br>返値が、ポインターだろうがint だろうが、正しく戻りますが、ポインターの<br>場合はポインターの示す先がどうなっているかが問題になるわけです。<br># 初めして(^ いつも読ませていただいています。

_ Linux好き事務員 (2003年11月18日 12:54)

いっぱんじんは、スタックやメモリの話をしないに1票!<br>事務員には、わからない話なのらー (^^)V

_ monyo (2003年11月18日 13:06)

まず<br><br>>> i = 1; <br>>の場合の i は何型の変数なんでしょ? <br>すみません。<br><br>int i =1;<br><br>のtypoです。<br><br>>返値が、ポインターだろうがint だろうが、正しく戻りますが、ポインターの <br>>場合はポインターの示す先がどうなっているかが問題になるわけです。 <br><br>そうですよね。<br><br>>「配列の値は保証できない」という理解でよいと思います。 <br>>より厳密に言えば、配列の値だけでなく、tako のポインタ <br>>(アドレス)そのものも無効です。 <br><br>だと、ポインタのアドレスそのものも保証できないと言われたので、えっと思ってました。<br>もちろん、ポインタだけ正当に戻っても、その先が開放されている(保証できない)ので意味がないというのは、理解してますです。<br>ということで、日記本文のような理解で大丈夫ですよね?

_ べんぢゃみん (2003年11月18日 14:21)

>ということで、日記本文のような理解で大丈夫ですよね? <br><br>微妙です。<br><br>>返値が、ポインターだろうがint だろうが、正しく戻りますが、ポインターの<br>>場合はポインターの示す先がどうなっているかが問題になるわけです。 <br><br>そうですね。例ではポインターの示す先がどうなっているかわからないのでなんとも言えないのです。<br><br>>になると思います(char tako[]="hoge"; とかの場合)。<br><br>この場合だと文字列定数"hoge"はスタックには取られないのでOKになってしまうのです。<br><br>>配列の実体は親関数に制御が戻った時点で解放されてしまうので<br><br>開放される領域なのかどうか、ポインタが何も示していないのでわかりません。<br><br>>だと、(この時点では)そもそも配列を指しているわけでは<br>>ないので、配列の値が保証できないのは当然として、ポイ<br>>ンタとしても何を指しているのかわからない、という意味<br>>で「tako のポインタが無効」と言いました。 <br><br>ということです。<br><br>日記で聞く内容ではないですね。詳しい方に直接聞かれた方が。いつも読ませて貰ってますm(_ _)m

_ べんぢゃみん (2003年11月18日 14:31)

例を勘違いしてました。例ではchar tako[]でwatayanさんの説明でもchar tako[]で、はせがわさんの説明でchar *takoだったのですね。char *tako="hoge"の場合だけです。忘れてくださって結構ですm(_ _)m

_ Tietew (2003年11月18日 14:34)

> >になると思います(char tako[]="hoge"; とかの場合)。 <br>> この場合だと文字列定数"hoge"はスタックには取られないのでOKになってしまうのです。 <br>違います。char *tako="hoge"; ならば tako の指す先は定数領域(静的)ですが,char tako[]="hoge"; はスタックに5バイト確保してからコピーされます。

_ Tietew (2003年11月18日 14:35)

あう,アセンブラリストを確認していたらすれ違った^^;;


Copyright (C) 2003-2017 TAKAHASHI, Motonobu
webmaster@monyo.com