c++ - std::strlen 如何在内部工作?

标签 c++ strlen

这个问题在这里已经有了答案:





How does the strlen function work internally?

(1 个回答)



strlen not checking for NULL

(6 个回答)


去年关闭。




我一直在努力理解 std::strlen()但徒劳无功:

AFAIK strlen()以字节为单位返回以空字符结尾的常量字符串中的字符数。如果它不是以 null 结尾的,则行为是未定义的。除此之外,还可以。

所以: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[] = "\0";
    const char cp3[] = "\0Hello";
    const char cp4[] = "H\0ello";
    const char cp5[1] = {};// UB?
    const char cp6[] = {'\0'};
    const char cp7[] = {'H', '\0'};

    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;
}

这是一个正确的实现。

关于c++ - std::strlen 如何在内部工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59843085/

相关文章:

c++ - 无法将 ‘std::string {aka std::basic_string<char>}’ 转换为 ‘char’ 作为返回

c++ - 有和没有事件循环的线程之间的区别

具有继承性的 C++ vector

c++ - 内存有效的方式来代表最短路径?

c++ - 为什么一个实体可以在内部范围内被重新利用? C++

C++使用指针算法查找字符串长度

c++ - 带有 strlen 的 SEGEGV 用于长字符串

c - 使用 FTS fts_open() 时 strlen 中的段错误

PHP strlen() 函数在 Enterkey 计数中的异常行为

CS50:For循环设计