std::strlen 在内部是如何工作的?
How does std::strlen wоrk internally?
我一直在努力理解 std::strlen()
但徒劳无功:
AFAIK strlen()
returns 以字节为单位的空终止常量字符串中的字符数。如果它不是空终止的,则行为未定义。除此之外,还可以。
所以:std::strlen("");
是 0。
但是,因为我在 www.cppreference.com 上读到了它,所以我找到了一个可能的实现方式:
// This is from: https://en.cppreference.com/w/cpp/string/byte/strlen
std::size_t strlen(const char* start) {
const char* end = start;
while(*++end != 0);// I think this causes UB
return end - start;
}
但如果我 运行 它:
int main()
{
const char cp1[] = "";
const char cp2[] = "[=12=]";
const char cp3[] = "[=12=]Hello";
const char cp4[] = "H[=12=]ello";
const char cp5[1] = {};// UB?
const char cp6[] = {'[=12=]'};
const char cp7[] = {'H', '[=12=]'};
cout << std::strlen(cp1) << " " << sizeof(cp1) << endl;// 0 1 OK
cout << strlen(cp1) << " " << sizeof(cp1) << endl;// 1 1 is UB?
cout << "\nDone!\n";
}
所以我看到的是网站上实现的版本触发了未定义的行为:循环在其条件下结合了预递增运算符和取消引用运算符,正如我们所知,运算符具有相同的优先级他们是从右到左评估的。因此,首先增加指针然后取消引用它。在空字符串的情况下,指针指向最后一个字符(空字符)之后的一个然后取消引用它,据我所知这是 UB。
您说得对,可能的实现具有未定义的行为。 *++end
递增然后取消引用,这是空字符串上的 UB,因为您取消引用了结束元素。
可能的实现从 been changed 到
std::size_t strlen(const char* start) {
const char* end = start;
while(*end++ != 0);
return end - start - 1;
}
这是一个正确的实现。
像这样 post inc,
std::size_t strlen(const char* const start) {
const char* end = start;
while(*end++ != 0); // fixing I think this causes UB
return --end - start;
}
我一直在努力理解 std::strlen()
但徒劳无功:
AFAIK strlen()
returns 以字节为单位的空终止常量字符串中的字符数。如果它不是空终止的,则行为未定义。除此之外,还可以。
所以:std::strlen("");
是 0。
但是,因为我在 www.cppreference.com 上读到了它,所以我找到了一个可能的实现方式:
// This is from: https://en.cppreference.com/w/cpp/string/byte/strlen
std::size_t strlen(const char* start) {
const char* end = start;
while(*++end != 0);// I think this causes UB
return end - start;
}
但如果我 运行 它:
int main()
{
const char cp1[] = "";
const char cp2[] = "[=12=]";
const char cp3[] = "[=12=]Hello";
const char cp4[] = "H[=12=]ello";
const char cp5[1] = {};// UB?
const char cp6[] = {'[=12=]'};
const char cp7[] = {'H', '[=12=]'};
cout << std::strlen(cp1) << " " << sizeof(cp1) << endl;// 0 1 OK
cout << strlen(cp1) << " " << sizeof(cp1) << endl;// 1 1 is UB?
cout << "\nDone!\n";
}
所以我看到的是网站上实现的版本触发了未定义的行为:循环在其条件下结合了预递增运算符和取消引用运算符,正如我们所知,运算符具有相同的优先级他们是从右到左评估的。因此,首先增加指针然后取消引用它。在空字符串的情况下,指针指向最后一个字符(空字符)之后的一个然后取消引用它,据我所知这是 UB。
您说得对,可能的实现具有未定义的行为。 *++end
递增然后取消引用,这是空字符串上的 UB,因为您取消引用了结束元素。
可能的实现从 been changed 到
std::size_t strlen(const char* start) {
const char* end = start;
while(*end++ != 0);
return end - start - 1;
}
这是一个正确的实现。
像这样 post inc,
std::size_t strlen(const char* const start) {
const char* end = start;
while(*end++ != 0); // fixing I think this causes UB
return --end - start;
}