首先,这里有一些代码:

int main() 
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", sizeof(days));
    printf("%u\n", sizeof(ptr));

    return 0;
}

是否有一种方法可以找出ptr指向的数组的大小(而不是仅仅给出它的大小,这在32位系统上是4个字节)?


当前回答

没有神奇的解决办法。C不是一种反射语言。对象不会自动知道它们是什么。

但你有很多选择:

显然,要添加一个参数 将调用包装在宏中并自动添加参数 使用更复杂的对象。定义一个包含动态数组和数组大小的结构。然后,传递结构的地址。

其他回答

答案是,“不。”

C程序员所做的就是将数组的大小存储在某个地方。它可以是结构的一部分,或者程序员可以欺骗一点,malloc()比要求的更多的内存,以便在数组开始之前存储长度值。

c++模板有一个干净的解决方案,不需要使用sizeof()。下面的getSize()函数返回任何静态数组的大小:

#include <cstddef>

template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
    return SIZE;
}

下面是一个foo_t结构的例子:

#include <cstddef>

template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
    return SIZE;
}

struct foo_t {
    int ball;
};

int main()
{
    foo_t foos3[] = {{1},{2},{3}};
    foo_t foos5[] = {{1},{2},{3},{4},{5}};
    printf("%u\n", getSize(foos3));
    printf("%u\n", getSize(foos5));

    return 0;
}

输出:

3
5

你可以这样做:

int days[] = { /*length:*/5, /*values:*/ 1,2,3,4,5 };
int *ptr = days + 1;
printf("array length: %u\n", ptr[-1]);
return 0;

大多数实现都有一个函数,告诉你使用malloc()或calloc()分配的对象的保留大小,例如GNU有malloc_usable_size()

但是,这将返回反转块的大小,它可以大于malloc()/realloc()的值。


有一个流行的宏,你可以定义它来查找数组中的元素数量(Microsoft CRT甚至为它提供了名为_countof的OOB):

#define countof(x) (sizeof(x)/sizeof((x)[0]))

然后你可以这样写:

int my_array[] = { ... some elements ... };
printf("%zu", countof(my_array)); // 'z' is correct type specifier for size_t