質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

5293閲覧

malloc関数について

ssspwp

総合スコア31

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/11/06 17:18

C

1#include<stdio.h> 2#include<string.h> 3 4int main() 5{ 6 char *str; 7 int num, i; 8 9 printf("何文字のaを用意しますか?\n"); 10 scanf_s("%d", &num); 11 12 str = (char *)malloc(sizeof(char) * (num + 1)); 13 if (!str) { 14 printf("メモリが確保できませんでした\n"); 15 return 1; 16 } 17 for (i = 0; i < num; i++) 18 { 19 *(str + i) = 'a'; 20 } 21 *(str + num) = '\0'; 22 23 printf("%sを用意しました。\n", str); 24 25 free(str); 26 27 return 0; 28}

ここの部分が複雑すぎてわかりません(-_-;)

C

1str = (char *)malloc(sizeof(char) * (num + 1));

①*は全部間接参照演算子?
②charはキャスト?
③sizeofがなぜ必要?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

下記のコード内に、間接参照演算子は一つもありません。

C

1str = (char *)malloc(sizeof(char) * (num + 1));
  • *char のアスタリスク

charのポインタ型であることを示すアスタリスクです。
mallocの戻り値はvoid *型なので、それをキャストするためにつけています。

  • mallocの引数内部のアスタリスク

ただの掛け算記号です。


mallocの概要
連続したメモリを動的に確保するための関数です。
引数は確保したいメモリの大きさ(バイト単位)、戻り値は先頭アドレスです。

引数の指定の仕方
ご提示のコードの場合、文字列の領域を確保しようとしていますね。

sizeof(char)で一文字あたりに必要な領域を知ることが出来ます。
さらに文字数+1をかけることで、文字列の表現に必要な容量を得られます。
1を足しているのは、終端にヌル文字を格納出来るようにするためです。

戻り値の解釈の仕方
ちょっとC言語の癖が出ている部分ですね。
C言語では、void *型の値は、どんなポインタ型にもキャスト出来ます

確保する領域がchar型だけとは限らないので、mallocはvoid *を返すように設計されています。

まとめ

①*は全部間接参照演算子?

前述のとおり、少なくとも引用部分には間接参照演算子はありません。
引用していない部分では、例えば*(str + i)の*は間接参照演算子ですね。

②charはキャスト?

charへのキャストではなく、char *へのキャストです。
ポインタ型変数もアドレスの値を格納しているだけですので、キャスト出来ます。

③sizeofがなぜ必要?

mallocに確保すべき領域を通達するためです。
環境によって型のサイズが異なるので、このようにsizeofを使う必要があります。
(charは常に1バイトだったと思いますが、ちょっと自信がないです。)

投稿2017/11/06 17:54

LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2017/11/07 00:08

「型 char,unsigned char 若しくは signed char(又はそれらの修飾版)をもつオペランドに適用した場合の結果は,1 とする。」ということで、sizeof(char) == 1は、言語仕様上保証されています。
LouiS0616

2017/11/07 00:30

合っているようで良かったです。ありがとうございます。
guest

0

malloc関数で動的にメモリを確保する処理になります。
malloc関数の使い方はシンプルにこうなります。

c

1malloc(確保したいメモリサイズ); 2 3戻り値:確保したメモリの先頭アドレス(void型のアドレス値)

難しいと感じるのは、mallocの前後の記述でしょう。

(char *)はキャストになります。
代入先の変数strchar*型で宣言してます。
それに対しmallocの戻り値はvoid型のアドレス値ですから、strに合うように型変換をしています。

sizeof(char) * (num + 1)の部分は確保したいサイズの計算です。
C言語では文字列の格納先は主にchar型の配列で表されます。
よってchar型のサイズがいくつ必要かを計算します。
必要な数は、scanfでの入力値+文字列終端を表すNULL文字を含めた数になります。
通常1文字1バイトなのでsizeof(char)は不要ですが、どんな環境でも対応できる作りにしているのではないかと思います。

投稿2017/11/06 23:48

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C

1str = (char *)malloc(sizeof(char) * (num + 1));

numに10が入ったとすると、最後尾に¥0をつけるために11Byteのメモリを確保して、その先頭ポインタをstrに代入しています。

あなたの言う通り、char型である事を前提で考えれば、sizeof(char)は不要です。
sizeof(char)は1なので下記でよいです。

C

1str = (char *)malloc(num + 1);

mallocの戻り値はvoid型のポインタです。下記のように書くと「型が違うよ」とエラーが出ると思います。

C

1str = malloc(num + 1);

char型のポインタに型を変えるために(char *)が必要になります。

投稿2017/11/06 23:57

uroncha

総合スコア54

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問