You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++函数内用数组指针实现Python len()获取数组长度结果异常

问题根因

你遇到的现象是C/C++的数组传参退化特性导致的:

  • 在main函数中操作的arr是完整的int[5]数组类型,&arr的类型为指向长度为5的int数组的指针int(*)[5],对其做+1操作时,地址偏移量为整个数组的大小(你测试中两个outside地址差为0x14即20字节,对应5个int的总大小),因此*(&arr +1) - arr计算得到的差值刚好是数组长度。
  • 当数组作为参数传递给函数时,会自动退化为普通的int类型指针int*,函数内的arrPtr是栈上独立存在的指针变量,和原数组没有绑定关系。此时&arrPtr取的是这个指针变量自身的栈地址,而非原数组的地址,对其+1仅偏移一个指针的大小(64位系统下为8字节),解引用后得到的是栈上的随机值,因此计算结果为随机数。
正确实现方案

方案1:模板推导(C++最推荐,编译期计算)

利用模板参数自动推导数组长度,参数传数组引用避免退化,完全无运行时开销,类型安全:

#include <iostream>
using namespace std;

template<typename T, size_t N>
size_t len(T (&arr)[N]) {
    return N;
}

int main(){
    int arr[] = {1,2,3,4,5};
    size_t lenArr = len(arr);
    cout << "length of array: " << lenArr;
    return 0;
}

如果传入普通指针作为参数,编译器会直接报错,避免误用。

方案2:宏实现(兼容C语言)

仅可在数组未退化的作用域内使用:

#define len(arr) (sizeof(arr) / sizeof(arr[0]))

注意:该宏不能在接收指针参数的函数内调用,否则会得到错误结果。

方案3:哨兵值实现(仅适用于允许特殊结尾标记的场景)

如果必须通过指针传参,可以约定数组末尾的哨兵值(如字符串的\0),遍历计数得到长度:

int len(int *arrPtr, int sentinel = 0) {
    int cnt = 0;
    while (arrPtr[cnt] != sentinel) cnt++;
    return cnt;
}

// 使用时需要给数组添加哨兵
// int arr[] = {1,2,3,4,5, 0};

该方案有运行时遍历开销,且会占用一个数组元素作为标记,仅适合特殊场景使用。

内容的提问来源于stack exchange,提问作者Suly Flachberger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:36:02