質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

222閲覧

c言語 動的確保 関数化

fumi6328

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/04/10 11:26

編集2019/04/10 13:03

質問

関数を使って動的確保をしたいのですが、どちらの書き方の方がいいですか?
また文法的に間違っていたら教えてくださいm(__)m

該当のソースコード

C

1//include 2 3int *sec1(int n){ 4 int *p = (int*)malloc(sizeof(int)*n); 5 return p; 6} 7 8void sec2(int n,int *p2){ 9 p2 = (int*)malloc(sizeof(int)*n); 10} 11 12 13///////////////////(追記)////////////////////////////////////// 14void Free1(int **p1){ 15 free(*p1); 16} 17 18void Free2(int *p2){ 19 free(p2); 20} 21////////////////////////////////////////////////////////////// 22 23int main() 24{ 25 int n = 1; 26 int *p1,*p2; 27 28 p1 = sec1(n); 29 sec2(n,p2); 30 31 Free1(&p1); 32 Free2(p2); 33 return 0; 34}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

本例では関数が小さすぎます。

現実的な関数でないので、一般的な議論になりません。ケースバイケースとしか回答できません。ちなみに、この程度の大きさの関数ならば、malloc、freeをそのまま使います。

投稿2019/04/10 13:57

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HogeAnimalLover

2019/04/10 14:38

強いていうと、「free直後にポインタ変数をNULL埋めする」というfreeラッパ関数ならば価値はあると思います。若干ですが。
guest

0

sec1の書き方のほうが可読性・再利用性の観点から好ましいと思います。

質問にある2つの関数(*sec1,sec2)の違いは、「戻り値の有無」になります。
そして、過去にあった同様の質問をみると、

引数を与えたら戻り値が返ってくる、というプログラミングモデルは人間にわかりやすい

参照を埋め込むよりは戻り値で済むなら戻り値で返します。

そういう依存の少ないメソッドを組み合わせてシステムを作ると
複雑なシステムでも後で変更しやすくなります。

などとコメントがされています。詳しくは以下の記事をご覧ください。

戻り値あり、戻り値なしの使い分けについて

ご参考になれば幸いです。

投稿2019/04/10 12:59

amahara_waya

総合スコア1029

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/04/10 22:03 編集

同意見です。 ・パラメータが少ない。 ・復帰値で判定が出来る など
guest

0

C

1void sec2(int n,int *p2){ 2 p2 = (int*)malloc(sizeof(int)*n); 3}

これ↑マチガイ。正しくは↓

C

1void sec2(int n,int **p2) { 2 *p2 = (int*)malloc(sizeof(int)*n); 3}

※呼び出し側も修正してな。

で、どっちがいいかは場合による。

投稿2019/04/10 11:31

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

sec2の間違いは他回答通りです。
sec1とsec2、またFree1とFree2のどちらが良いかということについては、どれもケースバイケースだし、もっと言えば不要な関数です。
元々1ステップで書ける処理なので関数化することに意味がないからです。
freeの関数化については、以下のようにNULLではないとき(動的確保されているとき)のみに解放するような処理が望ましいので、関数化する意義はあります。

c

1void Free(int *p){ 2 if(p){ 3 free(p); 4 } 5}

投稿2019/04/10 23:53

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

HogeAnimalLover

2019/04/14 10:01

これは不要では?「free(NULL)」は「何もしないこと」と定められているはずです。ポインタをNULL埋めすることのほうが有益です。
ttyp03

2019/04/14 11:32

今まで特に意識してなく、過去にそのような書き方をしてたのを見てたので、そのほうが安全だと思いこんでいたようです。 ひとつ勉強になりました。 ただし、注意してくださるなら"はず"という曖昧な情報ではなく、その根拠まで示してください。 すべてのコンパイラで保証されているならいいのですが、そうではないコンパイラがある可能性があるならまったく不要な処理とも言えないと思います。
guest

0

ベストアンサー

void sec2(int n,int *p2){

p2 = (int*)malloc(sizeof(int)*n);

}

これはだめですね

void sec2(int n,int **p2){
p2 = (int)malloc(sizeof(int)*n);
}

投稿2019/04/10 11:32

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fumi6328

2019/04/10 13:09

そうなんですか、ではもう一つだけ聞きたいのですが、freeを別関数内で行うとしたら Free1が正しくFree2は間違っているということですか?(追記したところです)
y_waiwai

2019/04/10 13:33 編集

なぜsec2がだめかというと、アドレスという値を返さなくてはならないのに、 p2 = なんやかや では、呼び出し元に値を返せないから、です そこで、アドレスのポインタを引数にすることで、ポインタの指し先にアドレスを設定するようにします で、Free1は間違ってはいない、けど、ここはアドレスのポインタにする必要はないです freeするのには、アドレスを渡せばいいだけで、呼び出し元に戻す必要はないからです #free1をfree2と間違って記述してたので訂正
fumi6328

2019/04/11 00:12

ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問