2013-10-14 38 views
2

鉴于以下代码:非空终止阵列++

#include<iostream> 
int main(){ 
    char container[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; 
    for(char* cptr = container; *cptr != 0; cptr++) 
    std::cout << *cptr << std::endl; 
    return 0; 
} 

它在序列中的每个予执行它一次打印这些字符。我不明白为什么循环会终止,因为我没有在容器数组末尾明确指定任何空终止符。请帮忙。

+0

它应该会导致分段错误 – Kunal

+3

根据环境的不同,您的容器之后的内存可能会用零初始化,导致空终止符发生在那里。然而,这是不能保证的,所以它可能发生在另一台机器上/不同的编译器设置/不同的事情上。 –

+0

未定义的行为,您可以预测运行时的代码行为。 –

回答

8

这只是运气,真的。

碰巧对应于container[7]的内存区域为0,所以你越来越幸运了。

超出数组范围是未定义的行为。就你而言,它恰好是你所希望的行为,但你不能依赖它。

+1

+但'幸运'应该''不幸';)它是不值得的情况下最好的。 –

+2

@GrijeshChauhan Heh。我没有说“祝你好运”或“运气不好”。 Sidharth--这是好运,“你的代码就像你喜欢的那样工作!”这是不幸的,因为如果/当你移动到任何其他系统时,你会得到一个没有出现在你的系统上的错误,所以很难追查到。 –

+0

@ Scott :):).... –

2

您正在运行调用未定义行为的数组末尾。一种可能的未定义的行为是它以一种看似合理的方式工作。在这种情况下,可能发生的情况是未定义的行为是用零填充你的数组。

1

您正在唤起未定义的行为。未定义的行为意味着“任何事情都可能发生”,其中有时包括你想要发生的事情。这就是这里发生的事情。

调用未定义行为的原因是因为当您访问元素container的末尾时,您正在从未初始化的内存中读取数据。

3

首先,您发布的代码有一个可怕的bug:cptr != 0应该是*cptr != 0。您应该检查给定地址处的字符是否为空,而不是指针本身为空。

其他答案和评论是正确的。获得正确输出的唯一原因是因为在容器数组的末尾碰巧存在一些归零内存。把container阵列的内部结构将有助于消除微胖编译器可能会以其他方式插入:

#include<iostream> 
int main(){ 
    struct { 
    char container[7]; 
    char alphabet[27]; 
    } x = { 
    {'a', 'b', 'c', 'd', 'e', 'f', 'g'}, 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 
    }; 
    for(char* cptr = x.container; *cptr != 0; cptr++) 
    std::cout << *cptr << std::endl; 
    return 0; 
} 

如果您运行此版本中,你会看到你的阵列'a' - 'g'印刷,那么它会跑过来进入第二个数组并打印'A' - 'Z',然后敲击该字符串末尾的空值。

+0

cptr!= 0是一个错字 –

+2

@sidharthsharma - 将来您可以测试您发布的代码以避免此类错别字。至少有一位其他评论者试图运行您发布的代码时感到困惑。 – DaoWen