(int *)の意味

このQ&Aのポイント
  • C++のmalloc関数は、指定された大きさの領域をヒープに割り当て、その領域の先頭のポインタを返す関数である。
  • 例えば、int *x; のようにポインタ変数を宣言し、malloc関数を使ってint型の領域を割り当てることができる。
  • その際、(int *)を使ってmallocから返されるポインタの型をintポインタとして指定する。
回答を見る
  • ベストアンサー

(int *)の意味

しょーもない質問すみません。 C++を独学中のプログラミング自体初学者です。 今読んでる教科書に、malloc関数の説明として、 指定された大きさの領域をヒープに割り当て、その領域の先頭のポインタを返す関数であるとあり、 例には、 .... int *x; x=(int *)malloc(sizeof(int)); *x=100; ..... などとあるのですが、malloc関数の前の(int *)は xはあくまで変数、malloc関数で帰ってくるのはpointerなので、 *でポインタから変数にした上で、その変数の型をintに強制的にしているという理解で合っているでしょうか?? どうも*がついている分、xはポインタのような気もして、混乱しています。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.6

int *x ; で宣言された変数x は 「int *」型 mallocが返すのは 「void * 」型 です。 x=malloc(sizeof(int)); では 「int * 」型 = 「void *」型 なので、型が一致しません。 そこで、 (int *)を使って、 「void *」型を「int *」型に型変換しています。 わざと「ポインタ」という言葉を使わずに説明しました。 混乱の原因は、ポインタを特別なものだと思い過ぎているからではないでしょうか。 ちなみに。 ・C++を使っているのなら、(型)というキャストは使わないようにするのがよいでしょう。 詳しくは「C++ キャスト」で検索すると解説サイトが見つかります ・C++では、領域割り当て用の演算子 new というものがあります。 これは、型を指定するので、キャストの必要はありません。 また、classやstructは、mallocで確保してしまうとコンストラクタが呼ばれません。 なお、mallocに対してfreeがあるように、new には deleteです。

samidare01
質問者

お礼

一番わかりやすかったのでBAにさせていただきます。 ありがとうございます。後半についても勉強していきます。

その他の回答 (5)

  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.5

追加です。 言語の仕様としてはいろいろなコンピュータ、OSに対応する必要があります。 よって >アドレスなのでintでもcharでも floatでも同じ長さではあるのですが、 と書きましたが、 intとcharとfloatで違うメモリーを使い、かつそのアドレスの長さが違う場合、 >代入の際には型を揃えることが重要なのです。 この文章が生きてきます。 int*にキャストしておくと問題なく解釈できます。

samidare01
質問者

お礼

わかりました、代入の際には型を揃えること。おぼえておきます。

回答No.4

しょーもない回答です。静的な意味で考えた場合、mallocは  void *malloc(size_t size); で定義されている(voidのpointer)のでxに代入するとき、(int *)でキャストしないとエラーか何かになるからでしょう。

samidare01
質問者

お礼

ありがとうございます。

  • ok-kaneto
  • ベストアンサー率39% (1798/4531)
回答No.3

>int *x; xはint型へのポインタです。 *xはxが指し示す中身です。 >x=(int *)malloc(sizeof(int)); sizeof(int)はint型変数の大きさ(バイト数)を返します。 malloc関数はメモリを指定された大きさだけ確保する関数で、 返却値はそのアドレス(void *型)です。 そのアドレスは(void *)型ですが、xは(int *)型です。 ですから、(int *)を付けることでキャスト(型変換)をしてxに確保したint型のアドレスを渡しています。 >*x=100; 先ほどのmalloc関数で確保したアドレスに100を格納しています。

samidare01
質問者

お礼

詳細な説明ありがとうございます!

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

>xはポインタのような気もして そのとおりです。 >x=(int *)malloc(sizeof(int)); int型1個分の領域を動的に確保して、 xがその場所を指すようにしています。 xはint型へのポインターですから、 *xはint型です。

samidare01
質問者

お礼

ずばりありがとうございます。やはりxはポインタの認識で良いのですね。

  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.1

sizeof(int)の長さの記憶域を取ります。 そしてそのアドレスをxに入れます。 アドレスなのでintでもcharでも floatでも同じ長さではあるのですが、 xがint* の型なのでint*にして代入します。 代入の際には型を揃えることが重要なのです。

samidare01
質問者

お礼

有難うございます。int*の型というところの理解ができていませんでした。

関連するQ&A

  • const int i ? int const i ?

    お世話になります 初歩的な事ですがよろしくお願い致します const 修飾子って変数型の前につけるの?後につけるの? //---------------------------------------------------- const int iTest1[] = { 0x0000, 0x0000 }; const int iTest2[] = { 0xFFFF, 0xFFFF }; const int* const piTest[] = { iTest1, iTest2 }; //---------------------------------------------------- const int 型のポインタ配列をロム領域に確保したい場合は変数の後にconst修飾子をつけると思います const const int* piTest[] = { iTest1, iTest2 }; これだとエラーとなるはずです。。。 そこで、疑問に思ったのが、私の書式だと、const intとconst修飾子は前に着けるのが普通だと思ってました //----------------------------------------------------   const int i = 0;   int const i = 0; //---------------------------------------------------- でも、どちらでもコンパイルは通ると思います 配置領域を確認した所、どちらもROMに確保されてました 一般的にどちらが正解なのでしょうか? const const int* piTest[] = { iTest1, iTest2 }; が、エラーになるという事は、int const i が正解なのでしょうか? 教授よろしくお願い致します ちなみに、組み込み系に特化した話になっています windows系とかだとconst宣言は何処にいくんですかね・・・ ヒープじゃない予備領域とかあるんですかね・・・

  • void型へのポインタ

    というのがC言語にありますよね? このvoid型へのポインタというのは、 どのようにイメージすればいいのでしょうか? 例えばchar型へのポインタなら、 指している領域は 1バイトの領域ですよね? ではvoid型は? また malloc関数を 使って char *p; p=(char *)malloc(1000); とするとでchar型にキャストしているから、 1個1バイト分の領域が1000個用意して、 先頭アドレスをpに格納するのですよね? では、 int *q; q=(int *)malloc(1000); としたら、用意されるのは、int型にキャストしているから 1個2バイト分の領域が500個用意されるのでしょうか? お願いします。

  • int型の変数値をバイト列としてコピー

    あるint型の変数に格納されている情報を、バイト列としてコピーする方法で困っています。 変数の入っている領域をそのままコピーしたいので、memcpyを使うかと思うですが、 コピーされた結果を見ると文字列の並びが逆転しているように見えます。 --サンプルコード抜粋 unsigned int i= 12345; unsigned char *c; c = (char *)malloc(sizeof(int)); printf("i_hex=%x\n",i); memcpy(c,(int *)&i,sizeof(int)); 出力結果 i_hex=3039 cの出力結果 3930000000 単純にmemcpyではダメなのでしょうか? 実行環境は、CentOS(32bit)+gccです。よろしくお願いします。

  • const int&の戻り値について

    const int&の戻り値について c++で「const int&(const int a)const{...」についてのメンバ関数がありますが、そのconst int&はどういう意図に使われるのでしょうか。 &があるので、アドレスを返すと思いますので、ポインタ変数に入れるだけでしょうか。それでもポインタ変数とメンバ関数の戻り値のアドレスは違うのはどういうことでしょうか。 主な使い用途がありましたら、教えてください。

  • ポインタのポインタとrealloc

    先程関数による動的確保について質問させていただき、ヒントを与えていただいたのですが、そこからまた疑問が生じました。 テストプログラムを作ったのですが、何やら動作がおかしいみたいです おかしい部分を抜き出したソースは次のとおりです int main() {  int **p;  int i;  p = (int **)malloc(sizeof(int *));  *p = (int *)malloc(sizeof(int));  p[0]=0;  for(i=1;i<10;i++){   *p = (int *)realloc(*p,sizeof(int)*(i+1));   *p[i] = i;  }  free(*p);  return 0; } 関数部として作りたい部分をメインにして抜き出しました。 このようにするとreallocがメモリ領域を拡張してくれなく(?)、*p[i] = i;の部分でエラー終了します。 ポインタのポインタではなく、ポインタを用いた時は正常に動作するのですが、何がまずいのでしょうか。 もし宜しければお願いいたします。 ちなみに私は学部4年生で、プログラムの使用は大学の研究用レベルです。

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

  • C言語、配列とポインタとアスタリスクの関係

    ちょっと行き詰まっています。 苦しんで覚えるCで勉強しているのですが、まさに苦しんでいます。 http://9cguide.appspot.com/19-01.html #include <stdio.h> #include <stdlib.h> int main() { int i; int *heap; heap = (int *)malloc(sizeof(int) * 10); if (heap == NULL) exit(0); for (i = 0;i < 10;i++) { heap[i] = i; } printf("%d\n",heap[5]); free(heap); return 0; } int *heap; ここで int ポインタを宣言しています。 heap = (int *)malloc(sizeof(int) * 10); ここでヒープを確保しています。(int *) のキャストも sizeof(int) も理解できました。 for (i = 0;i < 10;i++) { heap[i] = i; } まず1点目の疑問はここです。 変数 heap は「ポインタ変数」です。それでいて配列です。 ポインタ変数は、プログラムの文中で通常の変数として使うときには「*heap」のように先頭にアスタリスクを付けなければならかなったと記憶しています。 アスタリスクなしの「heap」はアドレス格納用の変数ではないでしょうか。 printf("%d\n",heap[5]); そして、その疑問をよそに、この命令が成り立っているようです。 画面上に出される結果は「5」であり、変数「heap」がただの配列として機能しているように見えます。 この printf 次のように書き換えると、エラーが出てコンパイルできませんでした。 書き換え実験1 printf("%p\n",*heap[5]); アスタリスクを付けて、通常の変数として扱い、受ける方も「%d」から「%p」に書き換えてアドレスを表示してみようと思ったのですが、 「「pointer」を付け忘れています。」というエラーが表示されました。 書き換え実験2 printf("%p\n",heap[5]); 受ける方を「%d」からポインタを受ける「%p」にしましたが、変数の方はアスタリスクなしです。 すると、結果はアドレス「00000005」が返ってきました。 (変数にアスタがないのになぜ?) 書き換え実験3 printf("%d\n",*heap[5]); これはもうめちゃくちゃですが、一応やってみました。コンパイルエラーで、 「「pointer」を付け忘れています。」というエラーが表示されました。 つまり、こういうことです。 0:printf("%d\n",heap[5]); //5 1:printf("%p\n",*heap[5]); //エラー 2:printf("%p\n",heap[5]); //00000005 3:printf("%d\n",*heap[5]);//エラー この結果から推測するに、アスタリスクはそもそも付けるとエラーになり、アドレスを表すか、そのアドレスに格納された値を表すかを切り替えるには、単にその変数を受ける「%d」や「%p」を変えるだけ、ということになるのだと思います。 mallocで返ってくるのは、ポインタ変数(の配列)だと思うので、変数のモードを切り替えるためにアスタリスクが必要なのだと思っていましたが、どこかで重大な勘違いをしているようです。 この件について、どなたか教えていただけないでしょうか。

  • このソースの意味を教えてください

    構造体を使ったリストを理解するためのソースで http://www9.plala.or.jp/sgwr-t/c/sec15-5.html のページに以下の関数が書いてありました。 自分はreturn p;とするのが自然であって、head = p;の意味が分かりません。それが不要な処理であるように思えます。 return head;としているのでその前にhead = p;は必要な処理ですが、無駄であって意味が無いように見えましたが、そのように書くのが自然なのでしょうか? head = p;の右に書いてあるコメントもおかしいと思うのですが、皆さんにはそのページのソースのその部分はコメントも含めて不自然さを感じないでしょうか? /*** リストにデータを登録 ***/ struct list *add_list(int key, char *name, struct list *head) {   struct list *p;   /* 記憶領域の確保 */   if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) {     printf("malloc error\n");     exit(EXIT_FAILURE);   }   /* リストにデータを登録 */   p->key = key;   strcpy(p->name, name);   /* ポインタのつなぎ換え */   p->next = head;  /* 今までの先頭ポインタを次ポインタに */   head = p;     /* 新たな領域を先頭ポインタに */   return head; }

  • mallocによる確保外の領域への参照

    構造体をmallocにより動的確保を行っていたのですが、例えば typedef struct _point{ int x, y; } point; point *pelem_point; pelem_point = (point *)malloc(sizeof(point)*5); このように、point型の構造体を5つ確保するとします。 しかし、 (pelem_point+100)->x = 1; (pelem_point+100)->y = 2; printf("%d\n", (pelem_point+100)->x); printf("%d\n", (pelem_point+100)->y); とやったら、確保していない100個先のところも構造体として利用できました。 なぜなのでしょうか。 自分の考えではこのようになりました。 mallocによりヒープ領域から適当な空いているメモリのアドレスが渡されるため、そこからはヒープ領域より先に、限りがあるまで進めてしまうために確保外のサイズにアクセスしても使えてしまっている。 また、mallocにより確保した場合は使用中のラベルがはられるため他に侵されることはないが、先の例のようにmallocによって確保してない場合はいくら使用できたとしても、空いているとコンピュータでは認識されるため、何かヒープ領域を使う場合に勝手に上書きされてしまう可能性がある。 しかし、この考えでも、なぜ確保外の領域が構造体のサイズ分ずつ区切られているのか納得いきません。 わかる方いましたらよろしくお願いします。

  • C言語のポインタ

    あまり意識せずにポインタを使っているせいか,次のプログラムではまってしまいました. #include<stdio.h> #include<stdlib.h> int main(void) {  int *p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  printf("%d\n", *p);  return 0; } コンパイルエラーで実行ファイルが出力されません. このプログラムで変数qはなぜポインタじゃないのでしょうか? 次にtypedefでptr_intという型を定義したプログラムは, 上のようなエラーが出力されず,期待とおりの結果になりました. #include<stdio.h> #include<stdlib.h> typedef int* ptr_int; int main(void) {  ptr_int p, q;  p = (int *)malloc(sizeof(int));  q = (int *)malloc(sizeof(int));  *p = 2;  *q = 3;  printf("%d\n", *p);  printf("%d\n", *q); return 0; } typedefすることでなぜエラーを回避することができるのでしょうか? よろしくおねがいします.

専門家に質問してみよう