• ベストアンサー

void*型のデータサイズ

すみません教えていただけますか? void*で宣言した変数にmallocで確保して mallocで確保したデーターサイズがわからないクラスで void*型のサイズを取得したいのですが できますか? よろしくお願いします。

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★アドバイス ・Windows の OS なら malloc() 関数の代わりに GlobalAlloc() という API関数を  使ってみたらどうでしょうか。  malloc() 関数も最終的には GlobalAlloc() 関数を呼び出しているようなので。  それで GlobalAlloc() で確保したメモリはあとで GlobalSize() 関数で取得できます。 ・下にそのサンプルを載せておきます。 サンプル: DWORD dwSize; DWORD dwMax; void *ptr; if ( (ptr = (int *)GlobalAlloc(GPTR,(sizeof(int) * 100))) != NULL ){  // 確保したサイズを取得  dwSize = GlobalSize( ptr );    // 確保した配列の要素数を計算  dwMax = (dwSize / sizeof(int));    GlobalFree( ptr ); } その他: ・void *とその確保サイズを表す構造体(クラスでも)を作って独自に管理する方が良いかも。  // 構造体の場合  typedef struct usermem_t {   void *buff;   size_t size;  } usermem_t;    // クラスの場合  class CUserMem {   void *m_buff;   size_t m_size;  private:   CUserMem();   CUserMem( size_t size );   ~CUserMem();   void *getBuff();   size_t getSize();  };  ↑  こんな感じで管理するとか。 ・以上。参考に。

参考URL:
http://msdn.microsoft.com/library/ja/jpmemory/html/_win32_globalsize.asp
psychesine
質問者

お礼

ありがとうございます 構造体の件、参考になりました。

その他の回答 (4)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.5

正確に自分がmallocしたサイズを後から知る方法はありません。 VCなどのWindows環境には取得用のAPIもありますが、 DebugモードやReleaseモードでメモリを割り当てる領域のサイズは 最適化され自分が意図しているサイズよりも大きい場合もあります、 したがって正確なサイズを期待しているのならば、そのサイズを知る 方法はありません。(配列として扱う添え字の最大値などで 使用するなどは絶対にしてはいけません。) 既に出ていますとおり、自分でそのサイズを管理するしかありません。

psychesine
質問者

お礼

ありがとうございます >DebugモードやReleaseモードでメモリを割り当てる領域のサイズは 最適化され自分が意図しているサイズよりも大きい場合もあり そんな事もあるんですね 勉強になりました

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

void*のサイズであればsizeof(void*)で得られますが、ポインタの参照先ということであれば原理的に不可能です。 どうしても取得する必要があるなら、参照先の最初辺りにサイズを入れておくか、ポインタとサイズを対にした対応表を作るなどして、別途管理する必要があります。 あと、すでに回答が出ているように、特定の処理系に特化するのであれば、方法がないわけではありません。

psychesine
質問者

お礼

ありがとうございます やっぱりそうですよね

  • fatbowler
  • ベストアンサー率48% (26/54)
回答No.2

普通にsizeof()で評価すると、ポインタの大きさ(システムによって違うけど 4バイトが多い)を返すだけですね。 グローバル変数なら話は違ってきますが、普通は分からないと思います。 0xFFFFFFFFとか無効値で初期化しておいて、それが何番目に出てくるか数える、 位しか思いつきませんが、何かうまい手があるなら私も参考にしたいですね。

psychesine
質問者

お礼

ありがとうございます やっぱりそうですよね

  • MrBan
  • ベストアンサー率53% (331/615)
回答No.1

「mallocで確保したサイズ」を後から知りたいということですか? であれば、標準的な方法ではできません。 mallocに渡したサイズを覚えておく必要があります。 処理系によっては、_msize等で取得できるものもありますが、汎用的ではなくなります。 > mallocで確保したデーターサイズがわからないクラスで > void*型のサイズを取得したいのですができますか? この言わんとするところが理解しがたかったのですが、クラスとはC++のクラスですか? # 最初の回答は、クラスはここでは特に関係ないものと解してのものです。 もしも欲しいのが「データサイズ」ではなく「型のサイズ」なのであれば、 # sizeofを使ってください。 # その他の意味であれば補足してください。

psychesine
質問者

お礼

ありがとうございます やっぱりそうですよね

関連するQ&A

  • Voidポインタで受け取った変数の型を調べる方法

    あるライブラリの関数を利用しようとしたのですが、その関数の引数にVoidポインタがあり、どういう型のデータを格納したのかわかりません。このポインタのアドレスに格納されたデータの型を調べる関数なり方法なりというのはあるのでしょうか。 Voidポインタというのは型を問わずに受け取れるというのは利点ですが、受け取ったものがあらかじめなんだかわからない場合はどうするのでしょうか。よろしくお願いします。

  • voidについて

    voidはデータの定義の無い型であり、代入演算子で代入する場合に、データとして参照するvoid型のメモリの領域は、代入先として参照するvoid以外の型のメモリの領域の型に変換されるという事でしょうか。

  • VBAデータ型一覧表の「記憶領域のサイズ」とは

    エクセルVBAの変数宣言時に使うデータ型一覧内に「記憶領域のサイズ」というのがありますがどういう意味でしょうか。 例   種類    表記  記憶領域のサイズ  データ範囲    バイト型  Byte  1バイト      0~255 宣言と同時に、変数(箱)を確保する最大必要メモリーを意味するということなら、変数にデータ範囲の限度255を入れたとすると3文字なので1バイトでは足りないのでは? 初心者ですよろしくお願いします。

  • C言語のvoid型ポインタ変数について。

    C言語のvoid型ポインタ変数について。 C言語のvoid型ポインタ変数について質問があります。 組み込み系の開発を行っているのですが、現在使用しているシステムで、 提供されている "API" を介してアプリケーション部のソフト作成を行っています。 この "API" ですが、引数の多くはvoid型ポインタとなっています。 ある人がこの引数がvoid型となっているのを見て、 『なんでvoid型なんや??、C言語でアセンブラと違うんやから、void型なんかにしない方が良い』 とおっしゃいました。 この意味がよくわからなかったのですが、なぜ void型はよろしくないんでしょうか? -- 僕が思うに、APIなんやから引数を void型ポインタ にすることでどんな型にも対応できる 汎用的であると感じ、逆にこの方が良いのではと感じたのですが。。 -API例---- int _exApiKannsuu( char in_data, void* out_data ) "in_data" をもとに "out_data" を取得する。 どーやらこの "out_data" が void型 であるのががよくないらしい・・

  • javaの「型」がよくわかりません。

    java初心者です。 本日、参考書を読んでいるとき、次のような式および文がありました。なお、以下はスーパークラスにpersonクラスがあり、studentクラスとteacherクラスが継承しています。personクラスがworkメソッドを持ってます。 //通常の3倍働いてもらう void work(Person p){ p.work(); p.work(); p.work(); } 「引数をperson型にしているので、このworkメソッドにはstudentクラスとteacherクラスのインスタンスも渡すことができます。」 私の中で、型はあくまで指示的なもの、および宣言に利用するものだと思ってました。基本型なら「この形のものを作るよ」とか、voidなら「戻り値はないんだよ」とか。 結局「型」とは何なんでしょうか? 初心者にもわかるよう、教えていただけないでしょうか?よろしくお願いします。

    • ベストアンサー
    • Java
  • データ型にVariant型みたいなのって存在するの?

    22歳男性っぽいです。 変数を宣言するとき、必ずデータ型を決メルト思うんですけど、この変数の型を固定せず、すべての値がはいるような型(variant型のようなもの)にするにはどうすればよいのでしょうか?

  • new と malloc によるメモリの動的確保について

    初めて投稿させて頂きます。よろしくお願い致します。 現在、以下のような、2次元配列による動的なメモリの確保を意図して、コードをC/C++にて記述しています。 (コンパイラはMINGW32のg++ 3.4.5) //mallocによるメモリ動的確保 data = (char **)malloc(num * sizeof(char*)); for(i=0; i<rowNum; i++){ data[i] = (char *)malloc(sizeof(char)*256); } //newによるメモリ動的確保 data = new char*[rowNum]; for(i=0; i<rowNum; i++){ data[i] = new char; } C++で書くのならば、 「mallocによるメモリ確保は辞め、newによるメモリ確保をしなさい」 という指摘が、書籍でもwebでもありましたので、 両方書き、両者を比べているのですが、理由がイマイチ分かりません。 10万行ほどのテキストデータで実験させてみたのですが、 mallocによる記述の方が、動作が数秒速いようなのです。 それで、new やmalloc で実際何をやっているのか、コードを見ようと思ったのですが、 newでは、 void* operator new(std::size_t) throw (std::bad_alloc); void* operator new[](std::size_t) throw (std::bad_alloc); void* operator new(std::size_t, const std::nothrow_t&) throw(); void* operator new[](std::size_t, const std::nothrow_t&) throw(); inline void* operator new(std::size_t, void* __p) throw() { return __p; } inline void* operator new[](std::size_t, void* __p) throw() { return __p; } というnewファイルの記述で行き詰まり、 malloc は malloc_allocator.hというファイルで行き詰りました。 以上を踏まえて、 1)そもそも、上記のメモリ動的確保記述はスマートな書き方なのか 2)実際に、newやmallocは、どういった手法でメモリ領域を確保しているのか 以上の2点について、ご教授下さい。よろしくお願い致します。

  • ASPで型宣言

    ASPにおいて変数宣言するとき dim xxx as String などの型宣言はできないでしょうか?? よろしくお願いします!!!

  • ファイルサイズの取得について

    2つのテキストファイルのサイズを取得し、そのファイルサイズ分だけを動的にメモリを確保しようとしています。 int *c,*a;と宣言し、 fp=fopen("./data/Problem.txt","r");//1つ目のファイル fseek(fp, 0, SEEK_END); /* ファイルの終端までシーク */ size = ftell(fp); /* 終端の位置、すなわちファイルサイズを得る */ fseek(fp, 0, SEEK_SET); /* ファイルの先頭に戻る */ c = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ while((x=fgetc(fp))!=EOF){ c[i]=x; i++; } c[i]='\0'; i=0; fclose(fp); fpa=fopen("./data/Answer.txt","r");//2つ目のファイル fseek(fpa, 0, SEEK_END); size = ftell(fpa); fseek(fpa, 0, SEEK_SET); a = (int *)malloc(size); while((x=fgetc(fpa))!=EOF){ a[n]=x; n++; } a[n]='\0';//・・・・(1) n=0; fclose(fpa); とすると1つ目のファイルの方だけはうまくいくのですが、(1)の部分で 「sample.exeの0x00411dcでハンドルされていない例外が発生しました:0xc0000005:場所0x0000000に書き込み中にアクセス違反が発生しました。。」 というエラーが出ます。 また、 int *c,*a;を int *c,a[300]; のように片方を配列として宣言し、 //a = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ のようにコメントアウトすると上記のエラーは出ずにcにメモリは確保されているようです。 これは何故なのでしょうか? また、どうすればaとcでメモリを確保出来るようになるのでしょうか? よろしくお願いいたします。

  • 2つのvoid関数でmallocを使うと2step目でセグメントエラーが出る

    プログラムのmainを見やすくするためにサブルーチンとしてvoid関数を使っているのですが、その中でmallocでメモリを確保して配列を作ろうとするとエラーが出てしまいます。概略を書くと #include <stdio.h> #include <math.h> #include <stdlib.h> //voidの宣言 void a(double* ,double*, double,); void b(double* ,double*, double,); main(){ double *c,*d,e; double *f,*g,h; c=(double *)malloc(sizeof(double)*N) //Nは適当な整数です d,f,gも同様の処理 色々な作業 while(適当回数繰り返します){ a(c,d,e); b(f,g,h); 色々な作業 } } void a (double* c, double* d, double e){ double **i,*j,; int k; i=(double **)malloc(sizeof(double *)*M) //Mは適当な整数です for(k=0;k<=M;k++){ i[k]=(double *)malloc(sizeof(double)*M) //Mは適当な整数です } jも同様にメモリ確保 様々な作業(逆行列の計算など) } void bはaとほとんど同じです。 mallocで二次元配列や配列を作っています。勿論同じ文字は使っていません。 以上のようなプログラムでgccは通ります。でも実行するとwhile内での1step目は上手くいくのですが、2step目のb内での始めの(double *)malloc(sizeof(double)*L)(Lは適当な整数です)で、つまりメモリ確保でセグメントエラーが出ます。両者とも片方を削るとエラーは出ません。1step目は何故上手くいくのか、2ステップ目で何故ダメなのかが分かりません。皆様の御教授をお願いします。