[英]How can I find the length of a character pointer using strlen() in C?
我明确表示我的问题与这个问题完全相同。
但不幸的是,我有一个问题,任何答案都没有解决。 所以代码是: -
#include <string.h>
int foo(void) {
char bar[128];
char *baz = &bar[0];
baz[127] = 0;
return strlen(baz);
}
问题是:这个功能的可能输出是什么?
当我运行这段代码时,每次都给出0,正确的答案是0和127(我仍然没有得到原因?)。
我的问题是这个语句是如何有效的我的意思是我们正在计算包含内存地址的baz
的长度,例如0xb96eb740
这是一个十六进制数,所以我们在这个地址上做strlen()
来查找它的长度? 我的意思是我们怎样才能找到一个地址的长度,这只是一个数字?
我真的很困惑,并试图理解它几个小时但仍然没有得到它。
不要因为它被传递一个地址而被困住。 strlen()
总是占用一个地址。 它的参数是一个const char *
,一个字符串的地址。 所有这些调用都传递完全相同的地址:
strlen(baz);
strlen(&bar[0]);
strlen(bar);
baz
被赋值为&bar[0]
,所以第一个和第二个是等价的。 数组衰减到指向其第一个元素的指针 ( array == &array[0]
),因此第二个和第三个元素是等价的。
我的意思是我们怎样才能找到一个地址的长度,这只是一个数字?
假设根据你的例子, bar == &bar[0] == baz == (char *) 0xb96eb740
。 strlen()
将首先检查内存位置0xb96eb740是否包含\\0
。 如果没有,它将检查0xb96eb741。 然后是0xb96eb742。 然后是0xb96eb743。 它将继续按顺序检查每个位置,直到找到\\0
。
我知道那是真的。 但是为什么
strlen(baz)
返回0?
正如链接的问答所解释的那样,行为是不确定的,因为bar[128]
数组的内容是未初始化的。 该阵列中可能有任何内容。 我们知道值的唯一单元格是bar[127]
,它被设置为\\0
。 所有其他人都没有初始化。
这意味着它们中的任何一个或全部,或者都不包含\\0
字符。 它可以从一次运行变为另一次运行,甚至从呼叫到呼叫。 每次调用foo()
都可以得到不同的结果。 这完全有可能。 结果将根据调用foo()
之前堆栈上的数据而变化。
当我运行这段代码时,每次都给出
0
,正确的答案是0
和127
(我仍然不明白为什么?)。
它可以在0和127之间的任意值返回由于你一定不要过分解读该程序会发生什么,当你运行它返回不确定的行为。 如果你再次运行程序,如果你在foo()
之前调用一组不同的函数,如果你事先运行一个不同的程序,如果你改变编译器,如果你在一周的另一天运行它,如果你运行它,则输出可能会有所不同您使用不同的操作系统等,等等。
我的问题是这个语句是如何有效的我的意思是我们正在计算包含内存地址的baz的长度,例如0xb96eb740这是一个十六进制数,所以我们在这个地址上做strlen()来查找它的长度?
strlen
函数接受一个地址作为参数,其行为是读取存储在该地址的字符。 (它不尝试读取地址的字符作为你似乎在暗示)。 如果该字符不是'\\0'
那么它将读取下一个地址的字符并查看是否为'\\0'
等。
你的问题的答案是任何事情都可能发生 。
阵列bar
未初始化。 只有bar[127]
显式设置为'\\0'
。 将未初始化的数组传递给strlen()
,通过传递指向bar[0]
baz
间接执行该操作,具有未定义的行为。
实际上,在没有陷阱值的现代体系结构中,函数foo()
具有未指定的行为,并且可以返回0
到127
之间的任何值,具体取决于调用时堆栈包含的内容。
在你的情况下,它返回0
因为在bar
的开头恰好有一个空字节,但你不能依赖它,并且对foo()
连续调用可能返回不同的值。
如果你运行一个在valgrind或其他内存清理工具下调用foo()
的程序,它可能会抱怨strlen()
访问未初始化的内存。
其他人已经说过价值是不确定的 ,所以我直接谈到这个:
我的意思是我们怎样才能找到一个地址的长度,这只是一个数字?
你没有。 字符串的长度是通过从您想要开始的地址开始按顺序读取内存来计算的,并在您点击第一个'\\0'
字符之前查看您需要走多远。 下面是一个如何实现返回字符串长度的函数的示例:
int strlen(char * str) {
int length=0;
while(str[length] != '\0')
length++;
return length;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.