こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

メモリとポインタと配列と

malloc()を使用して可変の変数を作り加工。
後々に参照するためにポインタの配列に格納したいと考えております。
malloc()を行った後は必ずfree()にてメモリを開放せねばなりませんが、開放するとポインタの配列に格納した値も消えてしまいます。
だからといって開放せずにいるとメモリリークが起きてしまいます。
この様な場合はどのようにすればよろしいのでしょうか?

大体以下のような処理を考えております。
ご教授願えれば幸いです。
****************************************
  char *p[100];
  for(int i=0;i<100;i++) {

    char *word1 = "あいう";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。
    int size = strlen(word1) + 1;
    char *memo1 = (char *)malloc(size);
    if (memo1 == NULL) {
      printf("メモリを割り当てられません\n");
      exit(1);
    }
    strcpy(memo1, word1);
    
    //・
    //・ *memo1 を利用した処理。
    //・

    char *word2 = "abc";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。
    size = strlen(word1) + 1 + strlen(word2) +1;
    char *memo2 = (char *)malloc(size);
    if (memo2 == NULL) {
      printf("メモリを割り当てられません\n");
      exit(1);
    }
    memset(memo2, 0x00, size); //初期化
    strcpy(memo2, word2);
    strcat(memo2, "\t");
    strcat(memo2, memo1);


    p[i] = NULL;
    p[i] = memo2;
    free(memo2);
    free(memo1);
  }
****************************************
宜しくお願いします。

投稿日時 - 2008-10-30 19:52:07

QNo.4441911

困ってます

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

●ポイント1
C++を使っているなら、malloc() & free()よりもnew & deleteの方が良いんじゃないかな。

●ポイント2
処理の流れが整理されてないように思います。
----------------------------------------------------------------------
  char *p[100];

  // ●配列pを初期化。
  for (int i = 0; i < 100; i++) {
    p[i] = 0;
  }
  
  // ●memo1を利用した処理?。
  for (int i = 0; i < 100; i++) {
    char *word1 = "あいう";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。
    int size = strlen(word1) + 1;
    // char *memo1 = (char *)malloc(size);
    char *memo1 = new char[size];
    if (memo1 == NULL) {
      printf("メモリを割り当てられません\n");
      exit(1);
    }
    strcpy(memo1, word1);
    
    //・
    //・ *memo1 を利用した処理。
    //・
    
    char *word2 = "abc";// ここでは固定文字を代入しているが、実際には何桁の文字列が入るかは不明。
    size = strlen(word1) + 1 + strlen(word2) +1;
    char *memo2 = (char *)malloc(size);
    if (memo2 == NULL) {
      printf("メモリを割り当てられません\n");
      exit(1);
    }
    memset(memo2, 0x00, size); //初期化
    strcpy(memo2, word2);
    strcat(memo2, "\t");
    strcat(memo2, memo1);
    
    p[i] = memo2;
    // free(memo1);
    delete [] memo1;
  }
  
  // ●メモリ解放処理
  for (int i = 0; i < 100; i++) {
    // free(p[i]);
    delete [] p[i];
    p[i] = 0;
  }
----------------------------------------------------------------------
やりたい処理はこんな感じかな。

投稿日時 - 2008-10-30 20:45:44

お礼

ありがとうございます!
まさにやりたかったことです。
環境的にはC++なのですが、全体的にCで書かれている為、上記をCに置換して試してみます。
forの外で配列分確保する。。。ここに気付けませんでした。
また memo1 を開放するのではなく、p を開放する。
これは勉強になりました。

投稿日時 - 2008-10-30 21:43:23

ANo.1

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

プログラムの仕様上、動的に確保した領域を二度と使わないと
わかった時点で開放する。
それだけ。

投稿日時 - 2008-10-30 21:14:48

お礼

回答ありがとうございます!
確保と開放のタイミングが掴めず悩んでおりました。
もっと学習いたします。

投稿日時 - 2008-10-30 21:47:35

ANo.2

 
>p[i] = memo2;
>free(memo2);

 この、"free(memo2)"は、"free(p[i])"と同じだということは、
判っているのでしょうか。
 

投稿日時 - 2008-10-30 21:07:24

お礼

回答ありがとうございます!
free(memo2) をしなければメモリーリーク。
free(memo2) をすればp[i] も消えてしまうため、悩んでおりました。

投稿日時 - 2008-10-30 21:46:02

あなたにオススメの質問