3

可以使用*(&arr+1)-arrwhich 计算数组长度,然后简化为(&arr)[1]-arrwhich 进一步简化为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

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

4

3 回答 3

5

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

只有 ifarr实际上是一个数组。在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;
}
于 2013-07-30T11:34:41.870 回答
3

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

于 2013-07-30T11:34:11.307 回答
3

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

于 2013-07-30T11:35:16.997 回答