【问题标题】:*char ending with double '\0'*char 以双 '\0' 结尾
【发布时间】:2017-06-09 14:42:44
【问题描述】:

由于某些字符串末尾缺少字符“\0”,我的代码崩溃了。

我很清楚为什么我们必须使用这个终止字符。我的问题是, 向字符数组添加潜在的第二个空字符是否有问题 - 以解决字符串问题?

我认为在每个字符串中添加一个 '\0' 比验证它是否需要然后添加它更便宜,但我不知道这是否是一件好事。

【问题讨论】:

  • 拥有'\0' 不是问题,除非您没有超出该字符数组的范围。您必须明白,拥有两次'\0' 意味着,任何字符串操作甚至都不知道还有第二个'\0'。他们会一直读到第一个'\0',然后就可以了。
  • '\0'(或 NUL)字符终止一个字符串。因此,根据定义,NUL 字符之后的任何内容都不是字符串的一部分。
  • 最好正确解决问题并找出您的某些字符串未正确终止的原因。双 nuls 不会造成太大的伤害,但会让人头疼。
  • 你的建议是不好的做法。只需首先使用 NUL 终止符句点正确构造字符串。
  • 如何验证字符串末尾是否有\0?没有办法做到这一点。

标签: c c-strings null-terminated nul


【解决方案1】:

在字符串末尾有两次这个char ('\0') 有问题吗?

这个问题不够清晰,因为“字符串”对人们来说意味着不同的东西。
让我们使用 C 规范定义,因为这是一篇 C 帖子。

string 是一个连续的字符序列,以第一个空字符终止并包括第一个空字符。 C11 §7.1.1 1

所以 string 不能有 2 个 null 字符,因为字符串在到达第一个字符时结束。 @Michael Walz

相反,重新解析为“向字符数组添加潜在的第二个空字符是否有问题 - 以解决字符串问题?”


尝试将空字符添加到字符串的问题是混淆。 str...() 函数使用上面定义的 C 字符串。

// If str1 was not a string, strcpy(str1, anything) would be undefined behavior.
strcpy(str1, "\0");  // no change to str1

char str2[] = "abc";
str2[strlen(str2)] = '\0'; // OK but only, re-assigns the \0 to a \0
// attempt to add another \0
str2[strlen(str2)+1] = '\0'; // Bad: assigning outside `str2[]` as the array is too small

char str3[10] = "abc";
str3[strlen(str3)+1] = '\0'; // OK, in this case
puts(str3);                  // Adding that \0 served no purpose

正如许多人评论的那样,添加一个备用的'\0' 并没有直接解决代码的根本问题。 @Haris@Malcolm McLean

未发布的代码是需要解决 @Yunnosch 的真正问题,而不是尝试附加第二个 '\0'

【讨论】:

  • 所以同意,实际上这正是我要求 MCVE 的原因,并详细说明。看来我的评论不清楚。
  • @Yunnosch 我不会发布 MCVE,对此感到抱歉。代码是我工作的企业的,我做不到。如果您真的不了解问题是如何发生的,我们使用 Asan 找到了它。它会改变内存并给我的软件施加压力以发现潜在的错误。
【解决方案2】:

我认为在每个字符串中添加一个 '\0' 比验证它是否需要然后添加它更便宜,但我不知道这是否是一件好事。

你会在哪里添加它?假设我们做了这样的事情:

char *p = malloc(32);

现在,如果我们知道分配的长度,我们可以将'\0' 作为分配区域的最后一个字符,如p[31] = '\0'。但是我们不知道字符串的内容应该有多长。如果应该只有foobar,那么仍然会有 25 字节的垃圾,如果处理或打印可能会导致其他问题。

更不用说如果你只有指向字符串的指针,那么就很难知道分配区域的长度。

修复你构建字符串的地方可能会更好。

【讨论】:

    【解决方案3】:

    拥有'\0' 不是问题,除非您没有超出该字符数组的范围。

    您必须明白,拥有两次'\0' 意味着,任何字符串操作甚至都不知道还有第二个'\0'。他们会一直读到第一个'\0',然后就可以了。对于他们来说,第一个 '\0' 是 Null 终止字符,之后应该没有任何内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-01
      • 1970-01-01
      • 2021-09-25
      • 2015-06-10
      • 1970-01-01
      • 2017-02-07
      • 1970-01-01
      • 2017-04-10
      相关资源
      最近更新 更多