如何找出C中分配在堆上的数组的大小?

问题描述 投票:0回答:2

我有以下 C 代码:

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

#define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
#define ARRAYSIZEWITHPTR(a) (&(a)[1] - a)

int main (void){

  int array[5] = {1,2,3,4,5};
  int* pArray = array;
  int* p = calloc(ARRAYSIZE(array), sizeof(int));
  
  assert(NULL != p);
  
  printf("size of array: %ld\n", ARRAYSIZE(array));
  printf("size of pArray: %ld\n", ARRAYSIZE(pArray));
  printf("size of p: %ld\n", ARRAYSIZE(p));
  printf("size of pArray: %ld\n", ARRAYSIZEWITHPTR(pArray));
  printf("size of p: %ld\n", ARRAYSIZEWITHPTR(p));

  free(p);

return 0;
}

当我编译这个程序时,我从 gcc 收到以下警告消息:

test.c: In function ‘main’:
test.c:5:33: warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements [-Wsizeof-pointer-div]
    5 | #define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
      |                                 ^
test.c:15:35: note: in expansion of macro ‘ARRAYSIZE’
   15 |   printf("size of pArray: %ld\n", ARRAYSIZE(pArray));
      |                                   ^~~~~~~~~
test.c:11:8: note: first ‘sizeof’ operand was declared here
   11 |   int* pArray = array;
      |        ^~~~~~
test.c:5:33: warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements [-Wsizeof-pointer-div]
    5 | #define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
      |                                 ^
test.c:16:30: note: in expansion of macro ‘ARRAYSIZE’
   16 |   printf("size of p: %ld\n", ARRAYSIZE(p));
      |                              ^~~~~~~~~
test.c:12:8: note: first ‘sizeof’ operand was declared here
   12 |   int* p = calloc(ARRAYSIZE(array), sizeof(int));
      |        ^

以下是程序输出:

size of array: 5
size of pArray: 2
size of p: 2
size of pArray: 1
size of p: 1
 

从程序输出中可以明显看出,只有当以数组名称作为参数调用宏时,我才能得到正确的值。但是,数组名不是指向数组第一个元素的指针吗?如果是这样,使用数组名称调用宏(产生正确的结果)与指向堆上数组的指针(不会产生正确的结果)之间的本质区别是什么?

从源代码中可以看出,我尝试了两种宏方法来获取在堆上创建的数组的大小,但没有成功。

所以下一个问题是,是否有可能在 C 编程中使用

calloc(

) 获取在堆上创建的数组的大小?

蒂亚

arrays c size
2个回答
2
投票
没有标准化的方法来找出从

malloc

/
calloc
/
realloc
 返回的指针指向多少分配的内存。程序员应该自己跟踪这一点。

在您的示例中,由于

p

pArray
 具有类型 
int *
 
sizeof(p)
sizeof(pArray)
 为您提供 
int *
 类型的大小,在您的系统上最有可能为 8。

但是,数组名不就是指向数组第一个元素的指针吗?

不,数组名称是一个数组,但是在大多数情况下,数组“衰减”为指向其第一个元素的指针。不发生这种情况的一种情况是当数组是

sizeof 运算符的操作数时,因此由于 array 具有数组类型,因此 sizeof(array)

 给出整个数组的大小。

有一些标准化方法可以了解 
malloc()

和朋友 (

0
投票
,

realloc

) 返回的内存块的分配大小。
在 GNU/Linux 上,函数 
malloc_usable_size()

的主要 Linux 发行版中绝对可用。您必须使用

-std=gnu99

 而不是 
-std=c99 进行编译(通常是 -std=gnuXX
 而不是 
-std=cXX
)。
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>

#define ARRAYSIZE(a) (sizeof(a))/(sizeof(a[0]))
#define ARRAYSIZEWITHPTR(a) (&(a)[1] - a)

int main (void){
    int array[5] = {1,2,3,4,5};
    int* p = calloc(ARRAYSIZE(array), sizeof(int));
    assert(p != NULL);

    printf("Allocated size: %zu\n", malloc_usable_size(p));
    free(p);
    return 0;
}
结果:

Allocated size: 24
    

© www.soinside.com 2019 - 2024. All rights reserved.