- ベストアンサー
ポインタについて
chirubouの回答
開放する/しない、については他の回答者さんの通りです。 「p = "ABC";確保されるとするとこの段階で確保されると思うのですが」 正確に言えば、確保されるのはこの文が実行される時でなく、プログラムの最初から既に確保されています。 int i = 1; とか char *p = "xyz"; とかで指定された「定数」はコンパイル時に認識され、プログラムの「定数領域」(正確には定数領域という呼び方はされていませんが、ここではコンパイラが検出した定数が集められた領域のこととします)に集められています。 例えば、Unix (Linux) では strings というコマンドがあって、プログラムの中に埋め込まれている文字列定数をプリントすることができます。ので、質問者さんのプログラムも "strings a.out" とすると沢山の文字列の中に "ABC" という文字列が表示されるハズです。 勘違いされているのは、 char *p; //定義 test(p); //testメソッドの呼び出し ・・・ //他の処理等 printf( %s, p ); //出力 void test(char *p){ p = "ABC"; // 確保 } とした時、void test(char*) は結果的に何もしていません。char *p = "ABC"; としていますが、変数 p は引数ですので、この関数から戻った時には、呼び出した方に何も影響を及ぼしません。ですからこのプログラムは正しく動きません。 char *p; //定義 p = test(); //testメソッドの呼び出し ・・・ //他の処理等 printf( "%s?n", p ); //出力 char *test(void){ char *p = "ABC"; return( p ); } とでもすべきでしょう。あるいは、ちょっと複雑になりますが、以下のようにすべきでしょう。 char *p; //定義 test(&p); //testメソッドの呼び出し ・・・ //他の処理等 printf( %s, p ); //出力 void test(char **p){ *p = "ABC"; } とすべきです。
関連するQ&A
- ポインタ配列の動的確保
ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char)); ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。
- ベストアンサー
- C・C++・C#
- 配列とポインタと同時に使用する宣言について
配列とポインタを同時に使用した場合、どのように確保されるのかイマイチ理解しきれていません。 例えば、 char *pointer[10]; と宣言した場合、 pointer[0]="ABC" pointer[1]="DEF" ・・・・ のようにポインタ型を配列で管理する、という風に認識しています。 一方で char (*pointer)[10] とした場合、どのように確保されるのでしょうか?
- 締切済み
- C・C++・C#
- ポインタのポインタの必要性
書物によるとポインタのポインタの使用例として「ポインタの配列」はポインタを使ってアクセスすることができます。」[*]とありますが、どうしてポインタのポインタが必要なのかがいまいちピンと来ません。 どういう場合なのかを知りたく思っています。 [*]サンプルスクリプト ===================================================== char *mnthp[3] = {/* ポインタの配列の宣言 */ "January", "February", "March" }; char **p1;/* 「ポインタのポインタ」の宣言 */ int i, j; p1=mnthp;/* 「ポインタのポインタ」にポインタの配列 */ /* の先頭番地を設定 */ /***** 例1 *****/ for (i = 0; i < 3; i++) {/* 「ポインタのポインタ」の値を変えずに */ printf("%s\n", *(p1 + i));/* 相対的に文字列を出力 */ } ==> このようなことをしなくとも printf("%s", mnthp[i]); で値を参照出来ると思われる。 ===================================================== [*] http://www9.plala.or.jp/sgwr-t/c/sec10-4.html 宜しくお願い致します。
- 締切済み
- C・C++・C#
- 文字列のメモリ保持期間とポインタについてわからないので教えてください。
文字列のメモリ保持期間とポインタについてわからないので教えてください。 よくポインタの説明に、文字列を使った下記のようなサンプルコードが紹介されます。 char* s; s = "abcdefg"; printf("%s",s); (http://www2.netf.org/pointer3.html から引用) この"abcdefg"により確保された領域がいつまで保持されるのかわかりません。 ・これを実行しているメソッドを抜けるまでなのか? ・free(s)するまでなのか?(free(s)しなければいけないのか?) この例だとprintfして終わっていますが、sを戻り値として返却して他で利用したり、オブジェクトを生成して、そのメンバ変数に obj1->field1 = "value"; というように格納して利用することとか考えると、領域は勝手に開放されず、やっぱり明示的にfreeするということでしょうか? freeしないといけない、なんて記述も見たことがなくよく理解できずにいます。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- ポインタで、実装メモリの先頭から100バイト分参照してみたい
いつもお世話になります。 Cの質問です。 ポインタの勉強中なのですが、ポインタを用いて、実装メモリの先頭から100バイト分を参照してみたい、と思いました。 先輩が言うには「メモリの先頭領域にはメモリのメーカーとか、文字コードが順番に入ってるよ」とのことなのですが、どうにもプログラムが作れません。 mallocでは、どうやら「コンパイル時にメモリ領域を確保する」らしく、指定したメモリ位置(つまりアドレス0)からxxバイト分確保することはできないようです。 私が試しに書いてみたソースは以下になります。 #include<stdio.h> #include<stdlib.h> int main(void){ int i; char *p; p = (char*)malloc(sizeof(char) * 100); for (i=0;i<100;i++){ printf("%c",*p); p++; } return (0); } アドバイスでもかまいませんので、ご指導いただけたらと思います。 よろしくお願いいたします。
- ベストアンサー
- C・C++・C#
- メモリとポインタと配列と
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); } **************************************** 宜しくお願いします。
- ベストアンサー
- C・C++・C#
お礼
有難うございます。 よくわかりました。 既存のソースは構造体の中の一つにポインタを定義してあり、 構造体を受け渡ししていた為、大丈夫なようでした。 (結果的に複雑な方の処理になっていたみたいです。) 自分が例題であげたソースのは空のポインタ(null)を渡してますね。。。 勉強になりました。