2012-01-05 11 views
1

に配列サイズを計算する:は、私は私のCコードで配列のサイズを計算するためのマクロを持っているC

#define sizearray(a) (sizeof(a)/sizeof((a)[0])) 

私はそれをテストするとき、それは静的に定義された配列のため正常に動作しますが、ないので、動的に定義された配列のために(参照します以下)。なぜこれが当てはまるのか分かりません。ヒープに割り当てられた配列のサイズを計算する方法はありますか?

/* test sizearray macro */ 
void testSIZEARRAY(void) 
{ 
    /* test case for statically defined array */ 
    int a[5] = {0,0,0,0,0}; 

    assert(sizearray(a) == 5); 

    /* test case for dynamically defined array */ 
    int *b; 

    b = calloc(5, sizeof(int)); 

    assert(sizearray(b) == 5); 

    free(b); 
} 
+2

sizeofはコンパイル時に評価されます。だから、それは不可能です。 – ordag

+1

[Cで動的に作成された構造体の配列の長さを取得する方法は?](http://stackoverflow.com/questions/8717267/how-to-get-the-length-of-a-dynamically-構造体の中に構造体を作成しました – dasblinkenlight

+0

[配列のサイズを計算する]の複製が可能です(http://stackoverflow.com/questions/720077/calculating-size-of-an-array) –

答えて

5

答えはノーである、サイズを取得するための標準的な方法がありません動的に割り当てられた配列の
すべての実用的な目的のために、あなた自身でそれを追跡する必要があります。

のWindows(Visual Studioの):_msize()

GCC: MSIZE() がでそれを見つけることができません

しかし、それを行う、いくつかのコンパイラ固有の方法がありますGCCドキュメント...

+1

一般的に言えば、動的に割り当てられた配列のサイズを計算する方法はありません。 – dbeer

+0

@dbeerええ、私はそれを追加します。ありがとう。 – Mysticial

+0

割り当てられたサイズまたは要求されたサイズを返しますか? – AProgrammer

4
int *b; 
... 
assert(sizearray(b) == 5); 

ポインタは配列ではありません。 bはここ

sizeof b == sizeof (int *) 

ポインタ型のオブジェクトに適用さsizeofオペレータがポインタ型のサイズと同じであり、割り当てのサイズと同等ではないint

へのポインタとして宣言されていますアレイ。

割り当てられた配列オブジェクトのサイズを知るには、割り当てられたものを調べる必要があります。あなたの例では、5 intのオブジェクトを割り当てるので、あなたの配列のサイズは次のとおりです。

5 * sizeof (int) 

(または同等の、5 * sizeof *b

3

上記のint * bのように、最初の要素へのポインタしかない場合、配列のサイズを計算する方法はありません。配列のサイズを別々に保存し、ポインタと一緒に使用するか、何らかの形で配列の終わりをマークする必要があります。後者の解決法は文字配列で使用されます。文字配列は通常NULLで終了します(最後の文字として\ 0があります)。この場合、そのような終了文字が出現するまでループすることによってサイズを計算することができます。

1

これは悪いアドバイスです。しないでください。

現在glibcmalloc()(ら)によって割り当てられたメモリを取得するには、次のことを試みることができる:

#include <stdlib.h> 
#include <stdio.h> 

#define GLIB_MSIZE_T size_t /* We need to have a four byte unsigned integer type 
           here. */ 

#define GLIB_MSIZE(p) \ 
     *((GLIB_MSIZE_T*) (((char*) p) - sizeof(GLIB_MSIZE_T))) 

int main(int iArgC, char ** ppszArgV) 
{ 
     if (1 >= iArgC) 
     { 
       fprintf(stderr, "usage: %s <bytes to allocate>\n", ppszArgV[0]); 
       return EXIT_FAILURE; 
     } 

     { 
       /* This conversion uing 'atol()' only works up until to a certain size 
        of the integer represented by 'ppszArgV[1]'. */ 
       size_t size = atol(ppszArgV[1]); 

       void * pv = malloc(size); 
       if (!pv) 
       { 
         fprintf(stderr, "Allocation of %u bytes failed.\n", size); 
         return EXIT_FAILURE; 
       } 

       printf("Asked for %u bytes, got %u bytes.\n", size, GLIB_MSIZE(pv)); 
     } 

     return EXIT_SUCCESS; 
} 

1が実際に割り当てられたメモリの量を得ることができるという事実のほかに、面白いですこのコードで支払うときに見られることは、ほとんどの場合、要求されたメモリのサイズ以上が割り当てられるということです。

いずれにせよ、後者は当初要求された正確なサイズでこれから情報を引き出すのは安全ではありません。

関連する問題