首页 > 解决方案 > 当没有更多空间时,编译器如何添加空终止符?

问题描述

我知道这个问题已经被问了一百万次了,但我仍然感到困惑。我故意使我的字符串大小等于其中的字符数:

int main()
{
    int i = 0;
    char str[5] = "check";
    while((str[i] != '\0') && (i != 10)){ // (i != 10) aborts the func
        printf("str[i] = %c\n", *(str+i));
        printf("i = %d\n", i);
        i++;
    }
}

输出是:

str[i] = c
i = 0
str[i] = h
i = 1
str[i] = e
i = 2
str[i] = c
i = 3
str[i] = k
i = 4

尽管没有分配空间,为什么它仍然在末尾存储空字符?它取决于编译器,还是它们都以相同的方式工作?

标签: cstringmemory-managementnull

解决方案


标准库有

字符串是由第一个空字符终止并包括第一个空字符的连续字符序列。

With char str[5] = "check";,str[]不是字符串,因为它缺少空字符str[]可以称为数组char


经过几次迭代后,使用while((str[i] != '\0') && (i != 10)){, 代码尝试str[5],这在str[]. 这是来自莫斯科的未定义行为( UB ) @Vlad。任何事情都可能发生。

在 OP 的情况下,UB 显然str[5]为零,​​结束了循环。这在随后的运行中可能会有所不同。

不要依赖这个结果。是UB。


尽管没有分配空间,为什么它仍然在末尾存储空字符?

循环可能已经结束,因为内存中的下一个 0 或其他原因。是UB。

它是否取决于编译器,

没有基于编译的指定行为。没有规范表明结果是一致的。是UB。

...或者他们都以同样的方式工作?

没有规范说明它们的工作方式相同。没有规范说明它们的工作方式不同。是UB。


推荐阅读