sizeof(arr)/sizeof(arr[0])仅对栈/全局原生数组有效;传参退化为指针、new分配、stl容器中均失效,应改用std::array::size()或显式传长度。

sizeof(arr) / sizeof(arr[0]) 为什么有时失效
这个写法只在数组是「栈上定义的原生数组」时才安全。一旦数组退化为指针(比如传入函数、动态分配、或作为类成员),sizeof(arr) 就变成指针大小(通常是 8),结果完全错误。
常见踩坑场景:
- 把数组传给函数后在函数内用
sizeof—— 此时形参已是T*,不是数组类型 -
int* arr = new int[10];,sizeof(arr)返回 8,不是 40 - 用
std::vector或std::array却误套用该公式
std::array 的 size() 是最稳的选择
如果你能控制数组定义方式,优先用 std::array。它的长度是编译期常量,size() 成员函数零开销、类型安全、不会退化。
示例:
std::array<int> arr = {1,2,3,4,5};
std::cout <p>注意:<code>std::array</code> 长度必须是编译期已知常量,不能是变量;它不支持运行时扩容,但正好匹配“固定长度数组”的语义。
</p>
<h3>函数内怎么安全拿到数组长度</h3>
<p>原生数组传参后无法自证长度,必须显式传递。C++ 没有内置的“带长度的数组类型”传参机制。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<p>可行做法:</p>
<ul>
<li>额外加一个参数:<code>void func(int arr[], std::size_t len)</code>
</li>
<li>用模板推导(推荐):<code>template<:size_t n> void func(int (&arr)[N]) { /* N 就是长度 */ }</:size_t></code>
</li>
<li>改用 <code>std::span<const int></const></code>(C++20),它携带数据+长度信息,且可接受原生数组、<code>std::vector</code>、<code>std::array</code> 等</li>
</ul>
<p>模板推导方式在调用时自动捕获长度,但只适用于实参确实是栈数组的情况;<code>std::span</code> 更通用,但需确认编译器支持 C++20。
</p>
<h3>new[] 分配的数组长度只能靠自己记</h3>
<p>动态分配的数组没有元信息存储长度。你用 <code>new int[10]</code>,系统不会帮你存下 <code>10</code> —— 这个数字必须由程序员显式保存。</p>
<p>正确姿势:</p>
<ul>
<li>用 <code>std::vector</code> 替代:它内部管理长度,<code>v.size()</code> 安全可靠</li>
<li>如果非用裸指针,必须配套存一个长度变量:<code>int* arr = new int[n];</code>,然后始终和 <code>n</code> 一起传递、一起释放</li>
<li>绝不要试图通过地址运算反推长度(比如 <code>end - begin</code>),因为 new 分配的内存块头部没有标准长度字段</li>
</ul>
<p>真正麻烦的从来不是“怎么算长度”,而是“谁负责维护这个长度”——一旦脱离栈数组上下文,长度就不再是语言特性,而是你的契约责任。</p></int>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










