C ++中的非空终止字符数组

Posted

技术标签:

【中文标题】C ++中的非空终止字符数组【英文标题】:Non null terminated array of characters in c++ 【发布时间】:2013-10-22 07:11:07 【问题描述】:

给定以下代码:

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

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

【问题讨论】:

应该会导致分段错误 根据环境的不同,你的容器之后的内存可能会被初始化为零,从而导致空终止符恰好在那里。但是,这并不能保证,因此它可能会在不同的机器/不同的编译器设置/不同的东西上失败。 未定义的行为,你可以预测代码在运行时的行为。 @VladLazarenko 有动态分析工具,如 valgrind 和电围栏,旨在发现这类问题。此外,堆分配器的调试版本通常将模式写入内存,以发现引用堆的问题。在这种情况下,它是堆栈内存,因此您可能需要其他东西。 这就是为什么它被称为未定义的行为。它可以格式化你的硬盘,点亮白宫的圣诞树,或者工作…… 【参考方案1】:

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

其他答案和cmets都是正确的。您获得正确输出的唯一原因是因为在容器数组的末尾恰好有一些归零的内存。将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',然后在结尾处点击 null字符串。

【讨论】:

@sidharthsharma - 将来您可以测试您发布的代码以避免此类拼写错误。这让至少其他一位试图运行您发布的代码的评论者感到困惑。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

这只是运气,真的。

恰好container[7]对应的内存区域为0,所以你走运了。

超出数组的界限是未定义的行为。在您的情况下,它恰好是您希望的行为,但您不能依赖它。

【讨论】:

+ 但 lucky 应该是 unlucky ;) 值得案例而不是最好的。 @GrijeshChauhan 呵呵。我没有说“好运气”或“坏运气”。 Sidharth - 幸运的是“你的代码可以按照你的意愿工作!”不幸的是,如果/当您移动到任何其他系统时,您会得到一个不会出现在您的系统上的错误,因此很难追踪。

以上是关于C ++中的非空终止字符数组的主要内容,如果未能解决你的问题,请参考以下文章

c语言字符串数组和字符数组有啥区别?

java codility 训练基因组范围查询

C语言数组字符串初值

C语言 怎么把字符数组中的字符赋值给字符变量

c语言 数组可以转换成字符串吗

C语言中怎么把字符数组里的数据存放到字符串数组中