当前位置:  开发笔记 > 编程语言 > 正文

如何找到'sizeof'(指向数组的指针)?

如何解决《如何找到'sizeof'(指向数组的指针)?》经验,为你挑选了5个好方法。

首先,这里是一些代码:

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个字节)?



1> Paul Tomblin..:

不,你不能.编译器不知道指针指向的是什么.有一些技巧,比如以已知的带外值结束数组,然后计算大小直到该值,但这不是使用sizeof.

另一个技巧是Zan提到的那个,就是在某个地方存放大小.例如,如果您正在动态分配数组,请分配一个大于您需要的块的块,在第一个int中存储大小,并返回ptr + 1作为指向数组的指针.当您需要大小时,递减指针并查看隐藏值.只记得从头开始释放整个块,而不仅仅是数组.


快速跟进,为什么没有一个可以按照免费方式返回大小的功能?
我很抱歉这个帖子发布得太晚了,但是如果编译器不知道指针指向什么,free怎么知道要清除多少内存?我知道这些信息是内部存储的,可以免费使用.所以我的问题是为什么编译器也可以这样做?
@ viki.omega9,因为free在运行时发现了这个大小.编译器无法知道大小,因为您可以根据运行时因素(命令行参数,文件内容,月相等)使数组具有不同的大小.
@ viki.omega9:要记住的另一件事是malloc/free系统记录的大小可能不是你要求的大小.你malloc 9字节得到16. Malloc 3K字节,得到4K.或者类似的情况.
好吧,如果你可以保证只用malloced内存调用该函数,并且库跟踪malloced内存的方式与我见过的最多(通过在返回的指针之前使用int),那么你可以编写一个.但是如果指针指向静态数组等,则会失败.同样,无法保证程序可以访问malloced内存的大小.

2> Zan Lynx..:

答案是不."

C程序员做的是在某处存储数组的大小.它可以是结构的一部分,或者程序员可以欺骗一点和malloc()更多的内存而不是请求,以便在数组开始之前存储长度值.


@Adam:很快.我在我的字符串实现列表中使用它.线性搜索速度超快,因为它是:加载大小,预取pos +大小,比较大小与搜索大小,如果等于strncmp,则移动到下一个字符串,重复.它比二进制搜索快大约500个字符串.
显然pascal字符串是excel运行如此之快的原因!
这是如何实现pascal字符串

3> Ryan..:

对于动态数组(malloc或C++ new),您需要存储其他人提到的数组大小,或者可能构建一个处理添加,删除,计数等的数组管理器结构.不幸的是,C不能做到这一点. C++,因为你基本上必须为你正在存储的每种不同的数组类型构建它,如果你需要管理多种类型的数组,这很麻烦.

对于静态数组,例如示例中的静态数组,有一个常用的宏用于获取大小,但不推荐使用它,因为它不检查参数是否真的是静态数组.宏虽然在实际代码中使用,例如在Linux内核头文件中,尽管它可能与下面的稍有不同:

#if !defined(ARRAY_SIZE)
    #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif

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

你可以google出于对这类宏的警惕.小心.

如果可能的话,C++ stdlib如vector,它更安全,更易于使用.


ARRAY_SIZE是各地实际程序员使用的常见范例.
是的,这是一种常见的范例.您仍然需要谨慎使用它,因为它很容易忘记并在动态阵列上使用它.
是的,好的一点,但问的问题是指针一,而不是静态数组.
如果它的参数是一个数组(即数组类型的表达式),`ARRAY_SIZE`宏总是有效.对于你所谓的"动态数组",你永远不会得到一个真正的"数组"(数组类型的表达式).(当然,你不能,因为数组类型在编译时包含它们的大小.)你只需要一个指向第一个元素的指针.您的异议"不检查参数是否真的是一个静态数组"并不是真正有效,因为它们是不同的,因为一个是数组而另一个不是.
有一个浮动的模板函数可以做同样的事情,但会阻止使用指针.

4> skurton..:

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

#include 

template
size_t getSize(T (&)[SIZE]) {
    return SIZE;
}

这是一个foo_t结构的示例:

#include 

template
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



5> 小智..:

对于这个具体的例子,是的,如果你使用typedef(见下文).当然,如果你这样做,你也可以使用SIZEOF_DAYS,因为你知道指针指向的是什么.

如果你有一个(void*)指针,就像malloc()等返回的那样,那么,不,没有办法确定指针所指向的数据结构,因此无法确定其大小.

#include 

#define NUM_DAYS 5
typedef int days_t[ NUM_DAYS ];
#define SIZEOF_DAYS ( sizeof( days_t ) )

int main() {
    days_t  days;
    days_t *ptr = &days; 

    printf( "SIZEOF_DAYS:  %u\n", SIZEOF_DAYS  );
    printf( "sizeof(days): %u\n", sizeof(days) );
    printf( "sizeof(*ptr): %u\n", sizeof(*ptr) );
    printf( "sizeof(ptr):  %u\n", sizeof(ptr)  );

    return 0;
} 

输出:

SIZEOF_DAYS:  20
sizeof(days): 20
sizeof(*ptr): 20
sizeof(ptr):  4

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有