• ベストアンサー

領域の開放がされているかどうかはどうやって調べればいいのでしょう。

#include <stdio.h> #include <stdlib.h> int main(void){ char *str; printf("&str : %d\n", &str); // ●領域割り当て前のアドレス(NULL) printf("str : %d\n", str); str = (char *)calloc(15, sizeof(char)); // (1)領域割り当て後のアドレス printf("str : %d\n", str); // str領域開放 free(str); // (2)領域解放後のアドレス printf("str : %d\n", str); return 1; } 開放した後は●と同じくNULLになると思っていたのですが、 実際に実験してみて(1)と(2)のアドレスが同じものでした。 アドレスは割り当てたままに見えますが、実際にはちゃんと開放されているのでしょうか? それとも、何か間違えているでしょうか。 よろしくお願いします。

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

  • ベストアンサー
  • BLK314
  • ベストアンサー率55% (84/152)
回答No.1

完全な誤解です。 freeはポインタをNULLにしたりはしません。 NULLポインタをfreeしても安全であることは定められています。 この2つを混同し、freeされるとNULLになる と理解されたのでしょう。 多重解放を防止するために freeしたポインタに"自力で"NULLを入れるのは よくつかわれる手法です。 プログラムの条件分岐等でmallocがバイパスされる ことも考慮して、ポインタはNULLで初期化しておくと さらに安全です。

sosida_hos
質問者

お礼

有難うございます。 慣れない難しい言い回しが多いですね。 色々な誤解から変な疑問がたくさんわきます。 また何かあったら質問させてください。

その他の回答 (2)

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.3

>開放した後は●と同じくNULLになると思っていたのですが、 そもそも、関数内のローカル変数であるchar *型変数の初期値が NULLであることは未保証です。 NULLであることを、間違いなく確認されましたか? なお、ポインタの値を出力する際の書式文字列は"%p"です。 "%d"ではありません。

sosida_hos
質問者

お礼

有難うございます。 本にも%pと書いてあったのですが、%pだと16進数で直感的に分かりづらかったので・・・

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

すでに回答ついていますので補足的に。 free()にポインタ変数の「アドレス」を渡していないので、どうがんばってもfree()内で引数に渡したポインタ変数の中身をNULLにすることはできません。 # defineで妙なコトやっていたりしたら別ですが…。

sosida_hos
質問者

お礼

なるほど。有難うございます。わかりました。

関連するQ&A

  • callocについて

    ccalloc関数を用いてメモリを確保し、15文字以下の名前をキーボードから入力を10人分繰り返し、その後にすべての名前を出力をしなさい、ただし配列は使用しないものとする。 という問題があるのですが、calloc関数を習ったことがなくうまくいかず、エラーかnullが出力されます。どなたか教えてください、お願いします。 *********ソース********* #include <stdio.h> #include <stdlib.h> void main(void) { int i; char *str; char *buf; /*メモリの確保*/ str = (char *)calloc(110, sizeof(char )); /*メモリが確保出来なかった時*/ if(str == NULL){ printf("メモリの確保ができません。"); exit(1); } /*キーボードからの入力*/ for(i = 0; i < 10 ;i++){ gets(buf); *str = *buf; str++; } /*名前の出力*/ for(i = 0; i < 10 ;i++){ printf("%s", *(str)); str++; } /* メモリの開放 */ free(str); }

  • C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問

    C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問です! ファイルを開いた後でエラーとなるのですが、何が足りないのでしょうか? ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int k,i=0; int num[10]; char na[10][20]; fp=fopen(argv[1],"r"); if(fp==NULL){ printf("ファイルを開けません\n"); return 1; }else{ printf("開けた\n"); } while(fgets(str,sizeof str,fp)!=NULL){ tp=strtok(str," "); num[i]=atoi(tp); tp=strtok(NULL," "); strcpy(na[i],tp); i++; } printf("%d\n%s\n",num[0],na[0]); printf("%d\n%s\n",num[1],na[1]); fclose(fp); return 0; }

  • reallocについて

    現在、領域を拡張しながら、 ファイルを読み込んで呼び元に返却するPGを作成しています。 reallocがうまくいかないので、試しに小さいのを作って みましたが、これだとreallocの2度目で落ちます。 100文字ずつ呼んでいるので、拡張も100文字ずつ行っています。 メモリ確保に失敗なら、まだ分かるのですが、 ちょっと理由がわかりません。 reallocを複数繰り返していることも問題だと思いますが、 まずは正常に処理を流したいと考えています。 よろしくお願いします。 ~~~~~~ソース~~~~~~~~ //ファイルを読み込んでから領域を確保する #include <stdio.h> #include <string.h> #include <stdlib.h> #define BUFF 100 int main() { FILE *fp; char tmp[BUFF+1]; char *str; int len = 0; fp = fopen( "c:/test.txt" , "rb" ); if(fp ==0){ printf("ファイルがありません\n"); return -1; } //領域を初期化 str = (char *)malloc(1); memset(str,'\0',sizeof(str)); while(feof(fp)==0){ memset(tmp,'\0',sizeof(tmp)); fgets(tmp,BUFF,fp); //領域を再確保 len += BUFF+1; if(NULL == ((char *)realloc(str,len))){ printf("メモリ確保エラー"); } //読み込んだ値を変数に追加 strcat(str,tmp); } printf("文字列\n\n%s\n",str); printf("長さ:%d\n",len); fclose(fp); return 0; }

  • 多元配列について(ANSI C)

    動的多元配列で、 Voidポインタに、多種の型がぶら下がった多元配列を作り、 読み書きをしたいのですがどのようにしたらよろしいでしょうか。 具体的には、 x[0][1]は、intで「2」が入っている x[0][4]は、intで「9」が入っている x[1][2]は、charでしかも文字列の配列で「goo」が入っている x[1][5]は、charでしかも文字列の配列で「教えて」が入っている x[0]は、int型の配列。X[1]は、文字列型の配列。 というようなものです。 一応ソースは作ってみたのですが、int型では問題なくいくのですが、 文字列は、コンパイルはできますが、実行すると予期せぬことが起きます。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) {      void **topPointa;      int * iDataInput;      int * iDataOutput ;      char * chDataInput;      char * chDataInput2;      char * chDataOutput1 ;      // ポインタアドレス用のメモリ確保      topPointa = (void *) calloc (10 , sizeof(void *));      if(topPointa == NULL) {           printf("メモリが確保できません\n");           exit(-1);      }      //int配列のメモリ確保      iDataInput = (int * ) calloc (10 , sizeof(int));      if(iDataInput == NULL) {           printf("メモリが確保できません\n");           exit(-1);      }      iDataInput[0] = 3 ;      iDataInput[1] = 4 ;      topPointa[0] = (void * ) &iDataInput;      //int配列の取り出し      iDataOutput = *(int *) topPointa[0];      printf( "int: %d\n", iDataOutput[0] );      printf( "int: %d\n", iDataOutput[1] );      //char配列 のメモリ確保      chDataInput = (char * ) calloc (10 , sizeof(char *));      if(chDataInput == NULL) {           printf("メモリが確保できません\n");           exit(-1);      }      chDataInput2 = (char * ) calloc (10 , sizeof(char));      if(chDataInput2 == NULL) {           printf("メモリが確保できません\n");           exit(-1);       }      strcpy(chDataInput2 , "hoe");      chDataInput[0] = &chDataInput2;      topPointa[1] = (void * ) &chDataInput;      //char配列の取り出し      chDataOutput1 = *(char *) topPointa[1];      printf( "char: %S\n", chDataOutput1[0] );      free(iDataInput);      free(chDataInput);      free(chDataInput2);      return 0; } 言語は、C言語ANCI Cでお願いします。 以上。よろしくお願いします。

  • C言語でファイルの内容を strtok関数 を使って数字と文字を分けて

    C言語でファイルの内容を strtok関数 を使って数字と文字を分けて配列に格納したいのですが、うまくできません。 どこが駄目なのかご指摘をお願いします! ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int i=0; int num[10]; char na[10]; fp=fopen(argv[1],"r"); while(fgets(str,sizeof str,fp)!=NULL); tp = strtok ( str, " " ); while(tp != NULL ) { num[i]=atoi(tp); tp = strtok( NULL," "); if ( tp != NULL ){ na[i]=*tp; } i++; } printf("%d\n%s",num[0],na[0]); printf("%d\n%s",num[1],na[1]); fclose(fp); return 0; }

  • どこがちがうのでしょうか?

    以下の二つのプログラムはユーザーが文字を入力し、80文字以下なら ピリオドを追加して表示するというものです。上はうまくいきますが、下はうまくいきません。なぜでしょうか? #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str);i<79;i++) strcat(str,"."); } printf("%s",str); } #include<stdio.h> #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str)+1;i<79;i++) str[i] = "."; } printf("%s",str); }

  • ファイルから文字列を読み出して16進数に変換

    test1.txtというファイルから文字列を読み出して16進数に変換、という処理をしたいのですがうまくいきません。どこがどう悪いのでしょうか?ご教授のほどお願いします。 ---------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { FILE *fp; char *fname = "test1.txt"; char str[100]; int num; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%s is not open.\n", fname ); return -1; } while( fgets(str, 100, fp ) != NULL ){ num = strtol(str, NULL, 16); printf( "%s", str ); printf("%x\n", num); //ここでうまく出力されません } fclose( fp ); return 0; } ---------------- ちなみに、test1.txtの中身は以下のようになってます。 44DB4147E6075A92E878EB68C44DD51F 5DCE86622D846BF272215A792AF31A3E 46FF69A29D3DF1D4842461B239256C26

  • ファイルの出力

    コマンドラインで指定したファイルの内容を一行ずつ表示するプログラムです。一行表示するごとに次の行も表示するか尋ねます。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int main(int argc, char *argv[]) {  FILE *fp;  char str[80];  char ch;  if (argc != 2){   printf("コマンドライン引数が違います\n");   exit(1);  }  if ((fp = fopen(argv[1],"r")) == NULL){   printf("ファイルが開けません");   exit(1);  }  while(!feof(fp)){   fgets(str, 79, fp);   if (!feof(fp)) printf("%s",str);   printf("追加しますか?(y/n)");   gets(str);   if ( toupper(*str) == 'N') break;   printf("\n");  }     if (fclose(fp) == EOF){   printf("ファイルを閉じれません\n");   exit(1);  }  return 0; } while文の   gets(str);  if ( toupper(*str) == 'N') break; この部分を  ch = getchar();  if ( toupper(ch) == 'N') break; でやると上手く実行できないのですが、なぜでずか?

  • 結果が不安定なプログラム

    配列に入れられた文字列を、別の配列に逆にして入れ、表示するというプログラムを作っています。 #include<stdio.h> #include<string.h> #include<stdlib.h> void main() {   char str1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", str2[] = "";   int i = 0, len = strlen(str1);   char *p1 = str1 + len - 1, *p2 = str2;   while(*(p1 - i) != str1[0] - 1) *(p2 + i) = *(p1 - i++);   printf("str1 = %s\n",p1 = str1);   printf("str2 = %s\n",p2); } 実行結果: str1 = ABCDEFGHIJKLMNOPQRSTUVWXYZ str2 = ZYXWVUTSRQPONMLKJIHGFEDCBA と出るのですが、この文字列を例えば"TANGOHYOJI"とかに変えてみると、実行は出来るんですがprintfの部分が表示されません。 また表示できても、文字が違う文字になって表示されたりします。 あと、この場合に使われている<stdlib.h>はどういった役割を果たしているのでしょうか?これがないとこのプログラムは動かなかったのですが・・。 どうかよろしくお願いします。

  • strncpy後のatoiがおかしい

    こんにちは。 C++をVS2005でやっています。 atoi関数を使っているんですが、10個の配列strにstrncpyをやると値がおかしくなります。 10個目に'\0'を代入させてやってみても駄目でした。 以下にソースを載せます。 #include <string.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> int main( void ) { char string[256]; char str[10]; char *moji = "12345464"; int l; // using template versions of strcpy_s and strcat_s: strcpy(string, "6877897898"); strcat(string, "strcpy_s"); strcat(string, "and"); // of course we can supply the size explicitly if we want to: strcat(string, "strcat_s!"); strncpy(str, string, 10); l = strtol(str,NULL,10);// 値が違う 6877897898にならない printf("str = %d\n", l); l = atoi(moji); printf("moji = %d\n", l); l = atoi(string);// 値が違う printf("string = %d\n", l); printf("String = %s\n", string); getchar(); return 0; } 表示結果 str = 2147483647 moji = 12345464 string = 2147483647 String = 6877897898 mojiは正常に動作しますから、ナル文字が原因なのかと思ってしまいますが。原因がいまいち分かりません。 よろしくお願いします。

専門家に質問してみよう