【问题标题】:Non null terminated array of characters in c++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 和电围栏,旨在发现这类问题。此外,堆分配器的调试版本通常将模式写入内存,以发现引用堆的问题。在这种情况下,它是堆栈内存,因此您可能需要其他东西。
  • 这就是为什么它被称为未定义的行为。它可以格式化你的硬盘,点亮白宫的圣诞树,或者工作……

标签: c++ arrays loops pointers char


【解决方案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 - 幸运的是“你的代码可以按照你的意愿工作!”不幸的是,如果/当您移动到任何其他系统时,您会得到一个不会出现在您的系统上的错误,因此很难追踪。
      猜你喜欢
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      • 1970-01-01
      • 2012-08-14
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      相关资源
      最近更新 更多