2012-01-05 90 views
1

我有一个宏在我的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 2012-01-05 22:26:54

+1

[如何获取C中动态创建的结构数组的长度?]的可能重复(http://stackoverflow.com/questions/8717267/how-to-get-the-length-of-a-dynamically- (c) – dasblinkenlight 2012-01-05 22:27:54

+0

[计算数组的大小]的可能的重复(http://stackoverflow.com/questions/720077/calculating-size-of-an-array) – 2012-01-05 22:49:52

回答

5

答案是否定的,有让大小没有标准的方式一个动态分配的数组。
出于所有实际目的,您必须自行跟踪。

不过,也有一些具体的编译器中的方法做到这一点:

的Windows(Visual Studio中):_msize()

GCC: MSIZE() 不能在找到它GCC文档...

+1

你可能会说一般来说没有办法计算动态分配数组的大小,你只需要跟踪它。 – dbeer 2012-01-05 22:36:15

+0

@dbeer是的,我会补充一点。谢谢。 – Mysticial 2012-01-05 22:37:09

+0

它会返回分配的大小还是所询问的大小? – AProgrammer 2012-01-06 16:01:24

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

指针是不是一个数组。 b被声明为指针int

这里

sizeof b == sizeof (int *) 

sizeof操作者施加到指针类型的对象是相同的指针类型的尺寸和不等同于所分配的大小阵列。

要知道分配的数组对象的大小,您必须检查分配的内容。在你的榜样,你分配的5 int一个对象,所以你的数组的大小是:

5 * sizeof (int) 

(或同等学历,5 * sizeof *b

3

如果你只有一个指向它的第一个元素的指针,就没有办法计算一个数组的大小(就像你在上面的例子中用int * b那样)。您需要单独存储数组大小并将其与指针一起使用,或者以某种方式标记数组的末尾。后一种解决方案用于字符数组,这些字符数组通常以空字符结尾(以\ 0作为其最后一个字符)。在这种情况下,您可以循环计算大小,直到遇到这种终止字符。

1

以下是不好的建议,不要这样做。

#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; 
} 

除了事实一个确实可以获得分配的内存量,有趣的:

来获得内存的malloc()当前glibc(等人),你可以试试下面的分配使用此代码支付时要看到的情况是,在大多数情况下,分配的内存大小超过了所请求的内存大小。

无论如何,后者使得它不安全,试图从原来要求的确切大小的信息。