使用指针的数组长度

array length using pointers

本文关键字:数组 指针      更新时间:2023-10-16
数组

长度可以使用*(&arr+1)-arr计算,然后简化为(&arr)[1]-arr进一步简化为1[&arr]-arr

但是,当在与完成内存分配不同的函数中计算长度时,会计算出错误的结果。

例如

#include <iostream> 
#define ARRAY_SIZE(arr) (1[&arr]-arr)      
using namespace std;
void func(int *arr)
{
    cout<<ARRAY_SIZE(arr)<<endl;
}
int main()
{
    int arr[]={1,2,3,4,5};
    cout<<ARRAY_SIZE(arr)<<endl;
    func(arr);
}

这给出了输出:

5
8

是什么导致了这种奇怪的行为?

数组长度可以使用 *(&arr+1(-arr 计算

仅当arr实际上是一个数组时。在func中,arr是一个指针,所以这会取消引用一个随机的记忆词,给出未定义的行为。

没有

办法告诉数组的大小,只给定一个指向其第一个元素的指针。您可以通过引用传递数组:

template <size_t N>
void func(int (&arr)[N]) {
    cout<<ARRAY_SIZE(arr)<<endl;
    cout<<N<<endl;               // equivalent, and less weird
}

使用相同的技术,我们可以重新实现ARRAY_SIZE而无需求助于预处理器或任何奇怪的指针算法:

template <size_t N>
size_t ARRAY_SIZE(int (&arr)[N]) {
    return N;
}

main()中,编译器知道arr是一个大小5 * sizeof(int)数组。func()编译器所知道的只是arr是指向内存块的指针 - 它没有关于数组大小的信息,甚至没有关于它是一个数组的信息(例如,它可能只是通过malloc()分配的内存块(。

当您将数组传递给函数时,它会衰减为指针,并且对其大小的知识将丢失。 func 可以接受任何大小的数组,那么如何确定大小呢?您必须将数组的大小作为额外参数传递,或者使用数据结构,例如 std::vector 或 (C++11( std::array,它们会跟踪它们的大小。