当前位置: 首页 > news >正文

[特殊字符] C 语言避坑指南:为什么我的 strlen 算出的是 40 而不是 10?

在 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"包含 5+1+2+1+1 = 10 个字符(含空格)。等等,让我们仔细数一下:a,b,c,d,e, ,f,g, ,t。一共是10个可见字符。
实际现象:用户反馈打印结果是40(或者其他的随机大数字),而不是预期的 10。

2. 深度解析:消失的\0

要理解这个问题,必须明白 C 语言字符串的两个铁律:

  1. 字符串在内存中是以空字符\0(ASCII 码为 0) 结尾的。
  2. strlen的工作原理是“向后遍历”,直到碰到\0为止,它不关心数组定义的大小,只关心内存里的内容。

让我们算一笔账:

  • 字符串内容:"abcde fg t"
  • 有效字符数:10 个。
  • 加上结束符\0:实际需要11个字节的空间。

然而,代码中定义了:

char arr[10] = ...;

数组大小只有10。这意味着编译器只能把前 10 个字符塞进去,第 11 个字节的\0被无情地截断了!

3. 为什么会是 40?

my_strlen开始工作时,它从arr[0]开始数:

  1. 它顺利地数完了数组内的 10 个字符。
  2. 因为它没找到\0,它不会停下来
  3. 它继续向高地址内存读取(数组越界访问)。
  4. 它在内存的“荒野”中继续寻找\0
  5. 直到向后读了很远(比如读了 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”的教训,能让你对内存边界多一份敬畏!


这篇博客的逻辑很顺,但标题有点长。要我帮你改几个更吸睛的短标题吗?

http://www.gsyq.cn/news/1625059.html

相关文章:

  • 《列表和元组到底是有什么异同呢?》
  • SAP-ABAP:SAP QM 检验结果录入核心利器:BAPI_INSPOPER_RECORDRESULTS 完全指南
  • 如何利用软件计算流域面积(Global Mapeer)
  • 为什么说“无需逐字雕琢”也能搞定朱雀 AI 判定?
  • Gemini 3.1 Pro与GPT-5.4工程选型指南:认知中枢vs执行引擎
  • 从沈管家看AI数字员工的技术演进:告别“聊天”,走向“执行”
  • 梯度下降实操指南:从原理到工业级调参避坑
  • OpenClaw部署安装常见问题汇总与解决方法
  • 不造假也会被撤稿?临床科研自查盲区很多人忽略
  • 计算机毕业设计之基于Java Web的医护系统的设计与实现
  • 海关政策法规查询进入大模型时代:监管要求、公告文件与业务规则如何智能问答
  • 终端clear命令失效
  • AI的技术栈全知道
  • JMeter测试SOAP接口全攻略:从WSDL解析到性能压测
  • 2026邮件网关怎么选?主流品牌实测排名与选型指南
  • 调味品品牌策划设计:视维以全案思维助力传统赛道焕新
  • Java毕设选题推荐:基于 SpringBoot 的水务运行监测与智能应急决策系统的设计与实现 智慧水务突发事件调度处置系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • 2026济宁黄金回收白银回收铂金回收旧料回收怎么选?五家高实价铂金白银线下门店测评清单 + 联系方式
  • 论文AI写作检测率高吗?2026最新检测数据
  • ACT:Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware
  • Doris离线部署与虚拟机扩容实战:从环境准备到资源管理的完整指南
  • SQL优化-索引扫描
  • 4563563
  • 2026年罗马尼亚EOR名义雇主服务商权威排行榜:揭晓五款精选五大方案
  • 合同管理的“三级跳”:道本×DeepSeek如何把三件事做到位
  • AI编程助手实战对比:Deepseek-V4 vs Claude-Opus工程能力深度解析
  • 仅限前500名开发者获取:LLM提示工程白皮书V3.2(含GPT-4.5适配层提示词迁移方案)
  • 2026视频去水印方法有哪些?靠谱视频去水印软件推荐
  • 新一代浏览器自动化框架:如何系统性解决Selenium的七大痛点
  • 生产级机器学习模型服务化落地实战指南