• ベストアンサー

動的に配列を確保した時の操作の仕方

---------------- ヘッダ ------------------- typdef struct _TAG { char *mes; // メッセージの先頭アドレス確保 } *pTAG; pTAG ptag; // ポインタ上に長さが違う文字列を確保 char *local_mes[] = { "テスト文字列だよ", "文字列は長さが違うよ", "教えて!goo", }; ------------------------------------------- ---------------- ソース ------------------- void main( void ) { // 先頭アドレスを確保する。 ptag->mes = *local_mes; 【ptag->mesを使い、文字列描画がしたい!】 } ------------------------------------------- ソースコードを長く書いてしまいそうなので、要点だけ絞りました。 【やりたい事】としては、 ptag->mes = *local_mes で、 ptag->mesから文字列を全て描画したいのですが、上手く行きません。 調べたところ、ptag->mesが一次元配列化してるらしく、 "テスト文字列だよ" <-- 16バイト + 1バイト 17バイトptag->mesを進めると、次の行まで行き着きますが、 sizeof関数も上手く扱えません。 sizeof( ptag->mes ) = 4 <? 是非とも解決策をお願いします。 開発環境は、 borland C++ compiler 5.5です。

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

サンプル -------- #include <stdio.h> char *str[]={ "test", "for", "next", "while", NULL }; void main(){ char **m=str; while(*m){ printf("%s\n",*m++); } }

jam_with_ju2
質問者

お礼

回答、有難う御座います。 解決策となりました。 ポインタのポインタが、こんなところで役に立つとは; 非常に助かりました。有難う御座いました!

その他の回答 (2)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

char **mes; として mes=local_mes; とすれば *mes++ で順繰り全部取り出せるのじゃないかと思います。

  • J_H
  • ベストアンサー率57% (11/19)
回答No.1

char *local_mes[] = { "テスト文字列だよ", "文字列は長さが違うよ", "教えて!goo", }; はイメージ的に、 char* s1 = "テスト文字列だよ"; char* s2 = "文字列は長さが違うよ"; char* s3 = "教えて!goo"; を配列に収めたものです。 local_mes[0] = s1 (ポインタ) local_mes[1] = s2 (ポインタ) local_mes[2] = s3 (ポインタ) *local_mes[] = {s1, s2, s3} local_mes[] は一次元配列で、 各要素が文字列へのポインタを格納してるわけです。 >> sizeof( ptag->mes ) = 4 ptag->mes はchar* なので、 sizeof(char*) と同じことです。 *c = "string"; だとして、 c は "string" を指すポインタ(char*)、ポインタのサイズは4。 *c は c[0](=s)、文字(char)のサイズは 1。 だから、 char *c : sizeof(c) = 4, sizeof(*c) = 1 非常に抽象的な答えになってしまいました。 回答というより、ヒントですね。。。

jam_with_ju2
質問者

お礼

回答、有難う御座います。 sizeofは使い方が難しいデス(汗) 大きなヒント、有難う御座いました。 色々と頑張って見ます。

関連するQ&A

  • 配列の動的確保

    No.847223 reallocについて No.847300 ポインタについて と質問させてもらい、御回答をいただき、理解した(つもりな)のですが、以下のことが実現できなくこまっております。 (以前の質問はこれを実現するために質問しました。) まず配列array[1][20]を用意します(つまり文字列最高20字格納できる要素数1個の配列を用意)。 そして動的にこの配列のサイズを変更して、なにか文字列を入力する毎に、代入するスペースを逐次確保したいわけです。(メモリが溢れない限りスペースを確保しまくる) そこでcallocやreallocの記述の仕方に困っています。 まず、callocについて char array[1][20]; char *pn, *pn2; pn = (char *)calloc(sizeof(array)/sizeof(char),sizeof(char)); このボイドポインタをキャストする部分にchar* と char** のどちらを使えばいいか、です。 そしてreallocについて、 if( (pn2 = (char *)realloc(pn, sizeof(array)*cnt)) == NULL ){ printf("メモリの確保失敗!\n"); exit(0); } pn=pn2; strcpy(pn[cnt],input); 【ただし、cntは毎回1づつ増加する。】 【inputはchar型の配列で、なんらかの文字列がはいっている。】 としているのですが、これもキャストの仕方がわかりませんし、strcpyで、セグメンテーションフォルトになります。構造体を使ったリスト形式も考えたのですが、reallocの使いかたを覚えたいのであえてこの形式で実現しようとしています。 結局どうしたいかというと、realloc部をforループさせて、cntを1ずつ増加させ、 pn[1][20] つぎは pn[2][20] つぎは pn[3][20] とどんどん増やしていきたいわけデス。 すこしわかりにくい説明だとおもいますが、不明点や、言い回しがオカシイ箇所があればご指摘下さい。

  • 「動的確保した2次元配列のメモリ解放」を関数化したい

    質問タイトルの通りですが、 「動的確保した2次元配列のメモリ解放」をC言語で関数化したいと思っています。しかし、関数の引数には動的確保した配列の先頭アドレスのみ渡す形にしたいです。そのような場合の関数化は可能ですか? どうもうまくいかず、困っています。 以下、具体的に、サンプルソースを記述します。 わかる方、よろしくお願いします。 //====================================================// #include<stdio.h> unsigned char** AllocByteArray2d(int column, int row); void FreeByteArray2d(unsigned char** box); int main(voidls){ unsigned char array**; array = AllocByteArray2d(2, 3); FreeByteArray2d(array); return 0; } unsigned char** AllocByteArray2d(int column, int row){ unsigned char* box; box = (unsigned char**)malloc( sizeof(unsigned char*)*column ) int i; for(i=0; i<column; i++){ box[i] = (unsigned char*)calloc( row, sizeof(unsigned char)); if(box[i] == NULL) exit(EXIT_FAILURE); } return box; } //引数では配列の先頭アドレスだけ渡す形にしたい void FreeByteArray2d(unsigned char** box){ //ここをどう書いたらいいかわからない }

  • 多元配列について(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でお願いします。 以上。よろしくお願いします。

  • 2次元配列の動的確保

    ある画像を読み込むため、その画像を格納できる幅、高さを持った配列を動的に確保しようと考えています。 幅をxsize、高さをysizeで次のように記述しました。 unsigned char **src; int i; src = (unsigned char**)malloc(sizeof(unsigned char*) * ysize); src[0] = (unsigned char*)malloc(sizeof(unsigned char) * xsize * ysize); for(i=1; i<ysize; i++) src[i] = (src[0] + i * xsize); わざわざポインタのポインタを使用したのは、動的に確保した配列を2次元的なアクセスをしたかったためです。 画像の読み込み時は fread(src[0], sizeof(unsigned char), xsize * ysize, fp); としています。 上に記述したソースは問題なく動作しました。 しかし、上の場合だと全ての配列を連続して確保することができません。つまりsrcでmallocを一回、src[0]でmallocを一回使っているため、ポインタの配列の直後に配列を確保する保障がありません。そこでいっぺんに確保することを考えました。 unsigned char **src; int i; src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize); for(i=0; i<ysize; i++) src[i] = (unsigned char *)(src + sizeof(unsigned char *) * ysize + i * xsize); このように組み上げ、読み込み時は上のfreadと同様に記述したところエラーが出てしまいました。 やはり一行目のmallocで無理やりsizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize分確保するのは失敗だったのでしょうか?

  • 動的メモリの確保の仕方がわからなくて困っています

    バージョンリソースの情報を取得しようと以下の関数をつくったのですがバージョンがうまく読み出せません。環境はVC6.0++です。 /*--------------------------------------------------------*/ char *get_version() { #pragma comment (lib, "version.lib") char szFileName[MAX_PATH]; DWORD dwZero = 0, dwVerInfoSize; unsigned char *szBufferBlock; void *szBufferVersion; UINT VersionLen; GetModuleFileName( NULL, szFileName, sizeof( szFileName)); dwVerInfoSize = GetFileVersionInfoSize( szFileName, &dwZero); if (dwVerInfoSize){ szBufferBlock = (unsigned char *)calloc( dwVerInfoSize, sizeof(char)); GetFileVersionInfo( szFileName, dwZero, dwVerInfoSize, szBufferBlock); if(!szBufferBlock){ } VerQueryValue( szBufferBlock, TEXT("\\StringFileInfo\\041104b0\\ProductVersion"), &szBufferVersion, &VersionLen); } free((void *)szBufferBlock); return (char *)szBufferVersion; }/*--------------------------------------------------------*/ unsigned char *szBufferBlock;を unsigned char szBufferBlock[1604];のようにして 静的に確保するとバージョンをちゃんと返すのですが、 上記のようにcallocをやnew演算子を使うとソソソソソソソソソソソソのような文字列しか返さなくなります。 原因がわかりません。教えてください。

  • 配列

    こんばんは。 Cを勉強中の者なのですが 前に配列についての内容で自分も分からない事があったので投稿しました。 キーで文字列を入力して関数に渡し、 関数側で引数(文字列データ分)のメモリを確保する事は 出来るのでしょうか。 #include <stdio.h> #include <stdlib.h> void test(char *hiki); int main(void){ char inp[256]; scanf("%s",&inp); printf("%s\n",inp); test(inp); return 0; } void test(char *hiki){ char *i; i = (char*)malloc( ); /* 「hiki」をつかって出来るの でしょうか? */ 全然急ぎとかではなく、ちょっと疑問に思った事なのですが教えていただけるとうれしいです。 (考え方がおかしかったらスミマセン)

  • ポインタ操作について

    C言語から離れている間にmallocの使い方がいまいちわからなくなってしまいました。 基本的な質問となりますが御教授ください。 (1)char **a の時 (2)char *a[10] の時 (3)char a[][10] の時 それぞれのメモリの確保の方法、解放の方法を御教授ください。 できれば、確保後のアクセス方法等も御教授ください。 上記したソースのような例を書いて頂けると幸いです。 サンプルrサイトでも結構です。 例えば、簡単な例を出すと・・・(間違っているかもしれないですが) (0)char *aの場合 /***************************************/ void kansuA(char a){ : } void kansuB(char *a){ : } //////////////////////////////////////// int main(int){ char *pa; pa = (char *)malloc( sizeof(char)*5 ); // 確保 memset(pa,0x00,sizeof(char)*5); strncpy(pa,"1234",4); kansuA(pa); // 値渡し kansuB(&pa); // アドレス渡し free(a); //解放 } /***************************************/ 宜しく御願致します。

  • 文字列を格納する配列を、動的なメモリ確保で処理したい

    文字数が一定でない文字列の一覧を、配列に格納したいと思っています。 "AAA" "BBBBB" "CC" このような文字列を配列に格納するのに普通にやるなら char test[3][24]; for(i=0;i<3;i++){ strcpy(test[i],file[i]); } (便宜上、file[0]には、"AAA",file[1]には"BBBBB"が格納されてるとします) こうやると、test[3][24]の24バイトとか余計に確保した分が無駄になるので、 必要な文字列の長さだけ配列を確保したいと考えています。 で、 char *test[3]; for(i=0;i<3;i++){ //sizeには、各文字列のサイズが格納してあります。ここではその部分省略しますが test[i]= (char*)malloc(size); strcpy(test[i],file[i]); } とやれば (イメージで) test[0]= "AAA" test[1]= "BBBBB" test[2]= "CC" となると思ったのですが、うまく処理されませんでした。 このような処理をさせたい場合根本的に違うのでしょうか。 わかりにくい説明ですが、どなたかご存知の方よろしくお願いします

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #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));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • メモリ領域の確保の仕方

    お世話になります。 メモリ領域の確保の仕方とポインタの動向についての質問です。 呼び出し側の関数testで領域Aを確保する。 関数test内で確保した領域に作業領域Bを加え作業をする。 関数testを抜けるときにreallocで呼び出し側から得た サイズに領域Aを戻す。 このときの動作についてなんですが //呼び出し側 void Main(){   DATA *data_p;//データ構造体   long datacount = 5;//データ数(5はテスト用の可変値   data_p = (DATA*)malloc(sizeof(DATA)*datacount);   test(data_p,datacount);   free((void*)(data_p); } //関数test test(DATA data[],long datacount){   DATA *sagyodata_p;   long a = datacount+5;   sagyodata_p = data;   //作業用に領域を広げる   sagyodata_p = (DATA*)malloc(sizeof(DATA)*a);   //領域サイズを戻す   realloc(((void*)sagyodata_p),sizeof(DATA)*datacount); } としたときに 関数testでdata_pを参照したポインタsagyodata_pの中身は問題ないでしょうか? 現在の実行環境 .NET2003 C++では問題なく動いているようですが。 sagyodata_p = data; sagyodata_p = (DATA*)malloc(sizeof(DATA)*a); とするより、 realloc(((void*)data),sizeof(DATA)*a); としたほうがよいのでしょうか? この2つの違いがどのくらいあるのかお教えいただけたら 助かります。 よろしくお願いします。

専門家に質問してみよう