请求解析C语言中strlen(S->S + n)的计算逻辑及输出规律
拆解
strlen(S->S + 5)的行为及你的代码问题 嘿,咱们先从你的代码核心问题说起——你遇到的“无规律输出”本质上是野指针访问导致的未定义行为,来一步步理清楚:
1. 你的代码里的致命问题:未初始化的指针
看这段代码:
struct S *S = (struct S *) malloc(sizeof(struct S));
你给结构体struct S分配了内存,但结构体里的成员char *S(不得不说这个命名太容易混淆了!建议以后结构体和成员用不同的名字,比如结构体叫struct StrWrapper,成员叫char *content)完全没有被初始化。这意味着S->S是一个野指针,它指向的内存地址是随机的,里面的内容也是不可预测的垃圾数据。
2. S->S + n到底是什么?
对于char*类型的指针,S->S + n是指针算术操作:
- 当
n是正数时,指针会向后偏移n个字节(因为char占1字节,偏移量正好是n); - 当
n是负数时,指针会向前偏移|n|个字节。
但问题在于,S->S本身就是野指针,所以S->S + n指向的内存区域完全是非法的、随机的——你根本不知道这块内存里存的是什么。
3. 为什么替换n后输出没规律?
strlen的工作原理是:从传入的指针位置开始,逐个字节读取,直到遇到第一个'\0'(字符串结束符)为止,返回读取到的字节数(不包括'\0')。
因为S->S + n指向的是随机内存,里面的'\0'位置是完全不确定的:
- 有时候可能刚偏移就遇到
'\0',返回0; - 有时候可能要走好几个字节才遇到,返回一个较大的数;
- 更糟的情况是,你可能访问了操作系统不允许程序访问的内存区域,直接触发段错误崩溃。
这些结果自然看起来毫无规律可言。
4. 怎么让结果变得确定?
你需要先给S->S分配有效的内存或者让它指向一个合法的字符串,比如:
// 方式1:指向一个字符串常量 S->S = "Hello, Stack Overflow!"; // 方式2:动态分配内存并复制内容 S->S = malloc(20); strcpy(S->S, "Hello, Stack Overflow!");
这时候再用strlen(S->S + n)就会有确定的结果了。比如上面的字符串"Hello, Stack Overflow!":
strlen(S->S + 0)就是整个字符串的长度,20;strlen(S->S + 5)是从第5个字符(索引从0开始,第5个是空格)开始到结尾的长度,也就是" Stack Overflow!"的长度,15。
小提醒
尽量避免用相同的名字命名结构体和它的成员,这会极大增加代码的可读性和维护难度,很容易把自己绕晕。
内容的提问来源于stack exchange,提问作者Noel Nosse
相关产品推荐
相关产品推荐

