【发布时间】:2019-01-17 17:10:39
【问题描述】:
我所做的所有阅读都表明,将非空终止字符数组传递给std::strlen 是未定义的行为,可能会导致程序崩溃。但是,下面的代码(在 Cygwin 上使用 g++ 编译)运行良好。
这是怎么回事?
char test_cases[4][80] = {{'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'}, {}, {'1'}, {'A', 'B', 'C'}};
size_t num_test_cases = std::size(test_cases); // C++17
for (size_t i = 0; i < num_test_cases; ++i)
{
std::cout << std::strlen(test_cases[i]) << std::endl;
}
输出:
13
0
1
3
【问题讨论】:
-
你认为你的字符串之后有什么?
-
迟早会遇到一个零值字符。但是您处于未定义的行为领域-它似乎只是“起作用”。
-
您的数组初始值设定项少于 80 个字符,因此剩余的字符用
'\0'填充。 -
@MatthieuBrucher 实际上它们是值初始化的,这导致零初始化。默认初始化会留下一个不确定的值。
-
解释反对意见(我不一定同意):询问“为什么我的代码应该具有未定义行为的正常工作?”通常效率不高,因为未定义的行为包括“一切正常”的可能性。现在,如果您非常努力尝试让坏事发生但仍然无法让它们发生,那可能确实是一个问题的理由。但除此之外,不要假设所有可能出错的事情都会出错(无论墨菲先生会告诉你什么)。
标签: c++ c-strings strlen array-initialization