在 C 语言的学习过程中字符串和数组的关系是新手最容易“翻车”的地方。今天我们来复盘一个非常经典的案例明明数出来只有 10 个字符为什么自定义的my_strlen函数打印结果却是 40这背后隐藏着一个关于内存边界和结束符\0的深刻教训。1. 案发现场还原让我们先看看导致问题的“罪魁祸首”代码#include stdio.h size_t my_strlen(const char *p) { size_t num 0; while(*p) { // 只要没遇到 \0 就继续数 num; p; } return num; } int main() { // ⚠️ 问题核心在这里手动指定了大小为 10 char arr[10] {abcde fg t}; printf(%zu, my_strlen(arr)); return 0; }预期结果字符串abcde fg t包含 51211 10 个字符含空格。等等让我们仔细数一下a,b,c,d,e, ,f,g, ,t。一共是10个可见字符。实际现象用户反馈打印结果是40或者其他的随机大数字而不是预期的 10。2. 深度解析消失的\0要理解这个问题必须明白 C 语言字符串的两个铁律字符串在内存中是以空字符\0(ASCII 码为 0) 结尾的。strlen的工作原理是“向后遍历”直到碰到\0为止它不关心数组定义的大小只关心内存里的内容。让我们算一笔账字符串内容abcde fg t有效字符数10 个。加上结束符\0实际需要11个字节的空间。然而代码中定义了char arr[10] ...;数组大小只有10。这意味着编译器只能把前 10 个字符塞进去第 11 个字节的\0被无情地截断了3. 为什么会是 40当my_strlen开始工作时它从arr[0]开始数它顺利地数完了数组内的 10 个字符。因为它没找到\0它不会停下来。它继续向高地址内存读取数组越界访问。它在内存的“荒野”中继续寻找\0。直到向后读了很远比如读了 30 个字节后碰巧在某个内存地址上遇到了一个值为0的字节它才停下来。结论那个诡异的数字40其实是10你的字符 30内存里的垃圾数据。这是一个典型的**缓冲区溢出Buffer Overflow**导致的未定义行为。4. 正确的打开方式为了避免这种“内存踩踏”事故我们有两种标准的修正方案方案一让编译器自动计算推荐 ✅不要手动指定数组大小让编译器根据字符串长度自动分配空间它会自动多留一个位置给\0。// 编译器会自动分配 11 个字节 char arr[] abcde fg t;方案二手动预留足够空间如果你一定要指定大小请确保大小 字符串长度。// 至少需要 11建议给大一点比如 20 或 64 char arr[20] abcde fg t;5. 总结在 C 语言中。字符串长度有效字符的个数。一旦丢失了\0strlen就会变成一把失控的尺子丈量到内存的尽头。希望这个“40”的教训能让你对内存边界多一份敬畏这篇博客的逻辑很顺但标题有点长。要我帮你改几个更吸睛的短标题吗