上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
どうも、本日2回目の更新のゆってぃです。
ステーキが食べたくて仕方ないので、これを書いたら近所のファミレスに行ってくる予定です(涎)

先日、後輩からmallocに関する質問を受けました。(前に出てきた後輩とは別の、お利口な後輩です)
僕の担当部分ではmallocを使うことは滅多にありません(というか、現在のリーダーから制御チーム(チームといっても僕ひとりですが)には動的メモリ確保禁止令が出ています…)ので実はよくわからないのですが、相手は大切な後輩。
わからないなんて言おうもんなら、もともと低い僕への信頼は光の速さで地に落ち、勢いあまってアルゼンチンから出てきます!


後輩の疑問は、以下のようなものでした。
(そもそも部署が違う上、その子はアプリ担当なので、コンパイラなどの詳細は一切不明なのですが…汗)
mallocの使い方があっているか知りたいと。

--後輩のソース--

int MainFunc(void){

 ACCOUNT *account;

 (略)

 CreateAccount(account);

 (略)

}

char CreateAccount(ACCOUNT *account){

 account = (ACCOUNT*)malloc(sizeof(ACCOUNT));
 if(accout == NULL) return -1;
 memset(account, 0, sizeof(ACCOUT));

 return 0;

}

--ここまで--

ビルドは通るけど、うまく動かないとの相談でした。
どこがどううまく動かないのかは聞いていませんが(笑)
このコードのどこがいけないのか知りたい、とのことでしたね。

そのコードになんかすごく違和感があったので、僕は次のように書き直させました。

--ゆってぃのソース--

int MainFunc(void){

 ACCOUNT *account;

 (略)

 account = CreateAccount();

 (略)

}

ACCOUNT* CreateAccount(void){

 ACCOUNT *account;

 account = (ACCOUNT*)malloc(sizeof(ACCOUNT));
 if(account == NULL){
   //[TODO]なにかしかるべき処理
 }
 memset(account, 0, sizeof(ACCOUNT));

 return account;

}

--ここまで--

一応、こうしたらうまく動くようになったそうです。

正直、後輩のコードがどうしてダメなのかよくわかりません!(ドヤ顔)

たぶんmallocうんぬんじゃなくて、まだ実態の与えられていないaccountを引数として渡しちゃってることがいけないような気がしないでもないのですが、自信がないのでこの辺はお茶を濁しておきましょう。

僕の書き方が正しいのかも微妙なのですが、まぁ、NGだったらコードレビューの時にあちらの部署の先輩からなんか指摘があるでしょう(笑)

ん?でもそのときに

あちらの部署の先輩T「おい!なんでこんな訳のわからん記述をしてるんだ!」
後輩「いや、あの、ゆってぃさんがこう書けって…」
先輩T「なにぃ!あの馬鹿、また適当なこと言いやがって!!とっちめてやる!!」

ってなったらイヤだなぁ…。うぅ…。

という訳で、もしこの記事をお読みになった方で
おまえ全然わかってねーじゃねえかよ!いいか、ここはな…
というイケメンな美女がいらっしゃいましたら、ご指摘いただければうれしいです(>_<)

関連記事
スポンサーサイト
コメント
malloc
もう既に解決かもしれませんが気付いたのでコメントさせて頂きます。

CreateAccount(ACCOUNT *account) という書き方だと
account というポインタ変数は、関数呼び出し時に領域確保され関数終了時に解放されてしまう「スタック領域」に確保されます。

malloc した後のアドレスをaccountに代入しても、関数終了とともにその領域ごと失われてしまいます。
領域確保した先を開放せずにポインタをNullにしてしまうので、free不可・参照不可のメモリ領域ができてしまいエラーとなると思います。

CreateAccount(ACCOUNT **account)
のようにポインタのポインタを使用すると多分うまくいくと思います。
代入は以下でいいかな?
*account = (ACCOUNT*)malloc(sizeof(ACCOUNT));

コンパイルとか実行してないので細かい部分でウソを書いてるかもしれませんが、
「スタック領域が解放されるため確保したメモリ領域が参照不可になってエラー」
というのは間違いないです。
Re: malloc
torisugariさん

コメントありがとうございます^^
自分の中では、全然解決済みではありませんでした(涙)

わかりやすいご説明をありがとうございます!
関数の引数は所詮、実引数のコピーに過ぎないという大前提を見落としていました…(汗)

また、ソースコードまで載せていただいてありがとうございます!
確かにこの書き方なら、呼び出し元の"account"(アドレス)そのものが書き換えられるので大丈夫ですね。
理解の定着もかねてgccでビルド&動作確認させて頂きましたが、全く問題はありませんでした^^

大変勉強になりました。
ありがとうございます!
コメントの投稿
トラックバック URL
トラックバック
ご訪問者様
プロフィール

ゆってぃ

Author:ゆってぃ
経歴7年の組み込み系・制御系エンジニアです。
("ど素人"という文言は取りました…笑)
ソフトウェア開発経験ゼロの状態から、なんとか実務がこなせるようになってきた現在に至るまでの経験を、備忘録代わりに綴っていきたいと思います。
入門者の方、大歓迎!
(上級者の方、ごめんなさい…)

あと、ブログには全然関係ないですが、Bumpy Headというバンドのギターをやっています。
ライブ情報なんかも書いたりすることがあるので、その時に「行ってもいいよ~」といった感じのコメントを戴けると、泣いて喜びます(泣)
ブログ読んでくださってる方なら、チケット代サービスしちゃいます!

最後に…滅多に流用することは無いでしょうが、このブログに書かれているソースは、特に指定の無い限りMITライセンスとします。ただし、一部それ以外のものもございますのでご注意下さい。
※ブログのリンク先にあるコードに関しては、リンク先のポリシーに従ってください。

最新記事
最新コメント
カテゴリ
RSSリンクの表示
メールフォーム

名前:
メール:
件名:
本文:

twitter
リンク
ブロとも申請フォーム
スポンサードリンク


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。