• ベストアンサー

ポインタのポインタの初期化法

 文字列をポインタを使って扱うとき、例えば、初期化は次のように行えますよね。 #include <stdlib.h> char *s; s = (char *)malloc(1000); (これに続いてscanf("%s", s);など)  これと同様にして、二次元の配列を、ポインタのポインタを使って表したいとき、 char **s; と宣言したものを、malloc()関数を使って初期化することはできるのでしょうか。よろしくお願いします。

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

  • ベストアンサー
回答No.2

mallocで2次元配列を確保するためには まず各行の先頭アドレスを確保してから、各行の先頭アドレスに各列を確保するようにします。 具体的には10行20列を確保したい場合 int c = 10, r = 20; char **s; s = (char**)malloc(c*sizeof(char*)); for(i=0; i<c; i++){   s[i] = (char*)malloc(r*sizeof(char)); } と確保します。 注意としてはメモリの解放のfreeは、メモリを確保した各場所で行わないと適正に解放されないので for(i=0; i<c; i++){   free(s[i]); } free(s); とします。

awa3yee
質問者

お礼

 ありがとうございます。大変よく分かりました。

すると、全ての回答が全文表示されます。

その他の回答 (7)

  • Gotthold
  • ベストアンサー率47% (396/832)
回答No.8

sizeof演算子は、アライメントが加味された値を返すのではありませんでしたか?>#7. > 何度もありがとうございます。よろしければ、問題点を具体的に指摘して下さいませんか。 以下のページの説明とかどうでしょう。 C言語-ポインタとメモリと型(構造体)の関係 (2) http://www.mm2d.net/c/c-15.shtml

awa3yee
質問者

お礼

 ありがとうございます。参照ページを一読しましたが、処理系依存の話ですか。また時間を取ってじっくりと勉強してみます。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

あれ? アライメントの問題が発生する可能性がまったくないとはいえないような気がする>#6.

awa3yee
質問者

お礼

 何度もありがとうございます。よろしければ、問題点を具体的に指摘して下さいませんか。

すると、全ての回答が全文表示されます。
回答No.6

No.2 と同じだが、一度のmalloc/freeで済ますには: #include <stdlib.h> #include <stdio.h> int main() { int R = 3; int C = 4; int i, j; int** data; /* 領域確保 */ int* p = (int*)malloc(sizeof(int*)*R + sizeof(int)*R*C); /* 初期化 */ data = (int**)p; (int**)p += R; for ( i = 0; i < R; ++i ) { data[i] = p; p += C; } /* 代入 */ for ( i = 0; i < R; ++i ) { for ( j = 0; j < C; ++j ) { data[i][j] = i*10 + j; } } /* 参照 */ for ( i = 0; i < R; ++i ) { printf("%p: ", data[i]); for ( j = 0; j < C; ++j ) { printf("%02d ", data[i][j]); } printf("\n"); } /* 領域解放 */ free(data); return 0; }

awa3yee
質問者

お礼

 ありがとうございます。

すると、全ての回答が全文表示されます。
回答No.5

C言語では、void*型からは任意の型へのポインタへ暗黙の内に型変換を行うので s = malloc(c*sizeof(char*)); と書いても大丈夫です。 C++では、void *から任意のポインター型への変換には明示的なキャストが必要なので、 上記の書き方ではエラーがでます。

awa3yee
質問者

お礼

 何度もご丁寧に、誠にありがとうございました。感謝致します。

すると、全ての回答が全文表示されます。
  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.4

>No.2さんのご回答のように、void *型からchar **型へのキャスト、というのは、必要ないのでしょうか。 #3には「してもいいし、しなくてもいい」と書いてるんですが。 必須じゃありませんので好きにしてください。 malloc()がどうのより、void *の意味を理解した方がいいんでしょうけど。

awa3yee
質問者

お礼

 済みません、ちゃんと書いてありましたね。void *の意味をよく勉強したいんですが、また機会があれば情報源を当たってみたいと思います。ありがとうございました。

すると、全ての回答が全文表示されます。
  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.3

>質問文に書いたみたいに、malloc()の戻り値をキャストしなくていいのでしょうか。 malloc()の戻り値の型はANSI-C準拠ならvoid *なのでキャストしてもしなくてもいいです。

awa3yee
質問者

お礼

 ありがとうございます。No.2さんのご回答のように、void *型からchar **型へのキャスト、というのは、必要ないのでしょうか。

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

ふつ~に s = malloc(sizeof *s); みたいに初期化できる.

awa3yee
質問者

お礼

 ありがとうございます。質問文に書いたみたいに、malloc()の戻り値をキャストしなくていいのでしょうか。

すると、全ての回答が全文表示されます。

関連するQ&A