【问题标题】:Are c styled strings safe?c 风格的字符串安全吗?
【发布时间】:2009-10-11 13:23:36
【问题描述】:

在 c/c++ 中,有些人使用 c 风格的字符串,例如:

char *str = "This is a c-styled string";

我的问题是这样安全吗?我看到的方式是他们创建了一个 char 指针,该指针指向一个 const 字符数组的第一个字母,但不能有其他东西,例如另一个变量覆盖内存中 char 数组的一部分吗?从而导致str在逻辑上无效?

【问题讨论】:

标签: c++ c c-strings


【解决方案1】:

如今,字符串常量被放置在二进制文件的只读部分中。如果您尝试写入只读部分中的地址,CPU 的内存管理单元将导致错误,您的应用程序将出现访问冲突或分段错误或其他一些依赖于操作系统的行为。

此外,如果您将字符串常量的类型声明为非 const,编译器会发出警告。

【讨论】:

  • 存储在内存的只读部分...现在一切都有意义了...谢谢~
  • 有一个相当大的非 Intel-y 环境,甚至非 MMU 环境,但情况并非如此。 C 或 C++ 标准中没有规定这种行为,因为它是未定义的(非常与实现定义的不同)。您可能想明确表示,这个答案是支持它的架构的常见做法,但绝不是强制性的。
  • 1 请调整参数@paxdiablo。
【解决方案2】:

但是不能用其他东西,例如另一个变量覆盖内存中的一部分 char 数组吗?

他们不得这样做。原因是你的 C 字符串文字是一个 constant 并且正确地它应该被声明为一个:

char const* str = "This is a c-styled string";

您的(非常量)代码仅在与旧版 C 代码不兼容的情况下才允许使用。尝试修改数据会导致未定义的行为。

【讨论】:

  • 真正的类型应该是 const char str[]。为什么会丢失编译时大小信息?
  • @fnieto:很好的评论。但是,这是否会被优化为指向一个文字,或者它是否总是被复制(尽管有const 限定符)?我不想复制我所有的文字字符串。
  • @fnieto:虽然语义不同。正如 Konrad 所说,如果它被声明为数组,您将获得静态分配的字符串的本地副本。使用 char 指针,您只需指向原始静态分配的字符串。
【解决方案3】:

事情就像你做的一样安全。您可以像覆盖字符串一样轻松地覆盖堆栈上的整数。实际上,您的问题中的内容更安全(在某些系统中),因为它很可能被放置在只读内存部分中。

如果人们不知道自己在做什么,就不应该使用 C。就像他们不应该在没有经过适当培训的情况下使用电锯一样。 C 的全部存在理由是一种系统编程语言。它为您提供了做您想做的事的全部权力。权力伴随着责任。

【讨论】:

    【解决方案4】:

    这是不安全的。但是 C/C++ 中的任何其他东西也是如此。您可以轻松覆盖其他对象使用的内存部分。

    【讨论】:

      【解决方案5】:

      它们与您的编程习惯一样安全。只要您知道如何正确使用它们,它们就完全安全。对于那些编程风格让人联想到瓷器店里的大象的人来说,这样的字符串可能并不安全。但是对于整个 C/C++ 语言也可以这样说。

      您原来的单行声明示例已经存在不安全的样式问题。在 C 和 C++ 中,字符串文字都是不可修改的左值。创建指向此类文字的 [长期存在的] 非常量指针不是一个好主意。通常应该如下所示

      const char *str = "This is a c-styled string";
      

      注意额外的“常量”。

      (这个特定的规则在 C 中不能总是遵循,但通常只需要在一些控制良好的本地化惯用代码中违反它。)

      【讨论】:

        【解决方案6】:

        实际上不要这样做:

        int *foo = 0x1234;
        byte[] bytes = (byte[]) foo;
        bytes[0] = 0x56;
        
        printf("%d\n", *foo);
        

        也就是说,任何指针如果被滥用都是危险的。

        【讨论】:

          【解决方案7】:

          取决于您所说的“安全”。

          它们的内在安全性并不低于 C/C++ 中任何其他使用指针的方法。一般来说,指针要求你非常小心内存。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-05-14
            • 1970-01-01
            • 2011-08-06
            • 1970-01-01
            • 2023-03-18
            • 1970-01-01
            • 2014-01-18
            • 2019-02-22
            相关资源
            最近更新 更多