• ベストアンサー

malloc後、frokを行った場合

unix(Solaris)系、CCコンパイラ初心者です。 質問内容は2点あります。 1点目 たとえば変数Aを親プロセスでmallocを行い、その後forkした場合は 変数Aは子プロセスにも引き継がれると思いますが、 解放する場合は親、子プロセス両方でfreeする必要はあるのでしょうか? 2点目 1点目のmallocした変数Aをshmで共有メモリにした場合は 親又は子どちらか片方でfreeすればよろしいのでしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.1

質問の表現が変できちんと理解されているか心配です。 まずmallocで確保するのはメモリ領域(アドレス空間)で、変数はそれを指すだけです。 forkではアドレス空間がコピーされますので、子プロセスではそれぞれに開放(free)しなければいけません。 2つ目、mallocした変数をshmで共有メモリにするという表現はいまいち分かりませんが、mallocする代りにshm_openしたのなら、子プロセスを作った後では両方のプロセスからオープンしている状態になっていますので、それぞれで閉じ(shm_unlink)なければいけません。 通常はmallocで確保したメモリも共有メモリもプロセス終了(あるいはexec)時には自動的に開放される(あるいは閉じられる)ので気にすることは少ないと思いますけど。 # forkしたまま長くexecしないプログラムって少ないのではないかな

dijtoy
質問者

お礼

お礼が本当に遅くなって申し訳ございません。 また、あんぽんたんな質問をしたのに関わらず ご回答ありがとうございます。 UNIX系が初心者でしたのでforkした後にexecする事すら分かってませんでした。(する必要が無い場合もあるとは思いますが) ご回答の内容を元に、プロセスの挙動をいろいろ調べて 必要な情報を知ることが出来ました。 ありがとうございます。

関連するQ&A

  • mallocについて

    まだ初心者で分からないところがあるのですが 例えば char *Buf; Buf=(char *)malloc(256); free(Buf); としますよね? それを、 グローバル変数(?)で「char *Buf」として 処理の途中途中で Buf=(char *)malloc(*適当) を、何回も使い 最後の解放されるときに free(Buf) (*適当 は、適当な数値) を使う事は大丈夫でしょうか? それとも、ちゃんとメモリを割り当て(?)たら 使ったあとすぐに、メモリを解除しなければ ならないのですか? よろしくお願いしますm(_ _)m

  • 大容量をmalloc()した後にfree()

    C言語でシステム開発しています。 大容量をmalloc()した後にfree()すると、プロセスが強制終了してしまいます。 malloc()のサイズが小さい場合は問題がありません。 こういった場合にプロセスが強制終了しない方法はないものでしょうか?。 ご存知の方がいらっしゃればお教えいただきたいです。 以上です。

  • mallocとfree

    struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(1); } とサンプルプログラムがあるのですが、if分の意味がわかりません。 また、mallocを使った場合freeで開放とあるのですが、 どういう意味なのかわかりません。 よろしければ、上記2つの点について教えてください。

  • UNIXでのプログラム

    UNIXでプロセス管理に関するC言語のプログラムを作りたいと思っています。そこで、次にあげる3つのことを表示したいのですが、どうすればよいかわかりません。教えてもらえませんか? fork()前のプロセスID 親プロセスでは自信のプロセスIDとそこで生成した子プロセスのID 子プロセスでは自身のプロセスIDと親のプロセスID よろしくお願いします。

  • メモリ確保エラー時の効率的な書き方

    mallocなどで複数の変数に対してメモリを確保する場合があると思います.例えば3つの変数の場合, char *a, *b, *c; a = (char *)malloc(100); if(a==NULL){ /* メモリ確保できなかったとき */ return (-1); } b = (char *)malloc(100); if(b==NULL){ free(a); return (-1); } c = (char *)malloc(100); if(c==NULL){ free(a); free(b); return (-1); } 変数が多くなるにつれて後から確保する変数のエラー処理(すでに確保したメモリのfree)が増えてしまうので,何か良い方法(コードが短くなるような)はないでしょうか?

  • fork1()とfork()の違い

    SolarisをターゲットとするC言語の開発をしなくてはいけなくなりました。 ところが、Solaris環境がないためとりあえずCygwinで開発を行っています。 そこで、まず既存の部分を動作させたいのですが、子プロセスの生成にfork1()を使用していてコンパイルエラーになります。 このfork1()とfork()の違いがわかるかたいたら教えてください。

  • gdbmみたいな簡易データベースライブラリ

    Unix系OSでC言語で、あるサービスのデーモンプロセスを開発しているのですが・・ 簡易データベース(キー1個に対して値1個が検索できるような)のライブラリで、且つ、mallocを内部で使わないタイプのライブラリ、ないでしょうか? 普通はgdbmなどを使うところなのですが、gdbmは内部でmallocを呼び出しているので、デーモンプロセスで継続的に使うには向かないかも?と思いまして・・ それとも、mallocやfreeを何度も呼び出すことによるガーベージコレクションの問題は、あまり気にしなくてよい、のでしょうか?

  • windowsでのプログラミングについてなんですけど。

    UNIXの本を読んでると、プログラムはexitシステムコールが呼ばれると、 freeregを呼び出し、malloc済みメモリをすべて開放し、共有メモリについても 参照が0になったら解放するようになっていて、仮にメモリリークする プログラムで会ってもプロセスを殺せば、そのプログラムのリークした分は すべて解放されるんですよ~~~それと同じ感覚で、windowsでプログラム やってる友達に聞いたら、プロセスを殺してもnewでリークしたのしっぱなしに なるっぽいよ~って言ってたんですよ。それって本当なんですか? てか本当ならあえてそうしてるメリットってあるんでしょうか?

  • プロセスの生成

    #include<stdio.h> #include <unistd.h> main(){ int i; printf("\t(%s)プロセスID.....%d\n","元",getpid()); printf("\t(%s)親プロセスID...%d\n","元",getppid()); if((i=fork())==0) { //子プロセスで実行する部分 printf("\t子プロセスでのfork()の値 : %d\n",i); printf("\t(%s)プロセスID.............%d\n","子",getpid()); printf("\t(%s)親プロセスID...........%d\n","子",getppid()); printf("子プロセスを終了します\n"); } else{//親プロセスで実行する部分 printf("\t親プロセスでのfork()の値 : %d\n",i); printf("\t(%s)プロセスID.............%d\n","親",getpid()); printf("\t(%s)親プロセスID...........%d\n","親",getppid()); printf("親プロセスを終了します\n"); } } fork関数の振る舞いについてです。 上記のプログラムをgccでコンパイルして実行した場合出力結果が /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ (元)プロセスID.....375 (元)親プロセスID...246 親プロセスでのfork()の値 : 376 子プロセスでのfork()の値 : 0 (子)プロセスID.............376 (子)親プロセスID...........375 子プロセスを終了します (親)プロセスID.............375 (親)親プロセスID...........246 親プロセスを終了します _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ という感じで出力されました。 fork関数がプロセスの複製を行っていることと、戻り値が0と376の2つであることはわかりました。 また子プロセスには0を親プロセスには376を返すこともわかりました。 感覚的にはif文の真である子プロセス側の記述文と偽である親プロセス側 の記述文が同時に実行されているのではないかと考えましたが 同時に実行されているのに printf("\t子プロセスでのfork()の値 : %d\n",i); printf("\t親プロセスでのfork()の値 : %d\n",i); で表示される値が違うのはなぜでしょうか。 i=fork()によって代入されているのはわかるのですが、 同時に実行されつつ何故2つの違う値をiは出力できるのかがわかりません。 また出力結果が _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ (元)プロセスID.....377 (元)親プロセスID...246 親プロセスでのfork()の値 : 378 (親)プロセスID.............377 (親)親プロセスID...........246 親プロセスを終了します 子プロセスでのfork()の値 : 0 (子)プロセスID.............378 (子)親プロセスID...........1 子プロセスを終了します _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 子プロセスから見たときの親プロセスが1となっているのは何故でしょうか? 本来ならば377ではないでしょうか? わかりにくい説明ですいません。 よろしくお願いします。

  • コマンド実行結果のエラー標準出力制御について

    unix-cにて子プロセスにてexecvp()を使用しmailxコマンドを実行し、親プロセスにてmailxコマンドの実行結果に出力処理をしたいのですが、 どんなことがあろうと(パスが違うなど)標準出力させたくありません。 現在、fork(),pipe()を駆使して正常系は上手くできるようになったのですが、エラー時の標準出力(親、子とも)を防ぐことが できません。何か良い方法はないでしょうか?

専門家に質問してみよう