【问题标题】:How does this line of code work?这行代码是如何工作的?
【发布时间】:2011-12-10 17:21:48
【问题描述】:

所以我最近在查看某人的代码,发现编译器没有抱怨,也没有出现以下任何运行时错误:

const char *p = "I didn't malloc...";

上面的代码有效,但我想知道如何。这就是我认为正在发生的事情。谁能确认一下?

所以“我没有 malloc...”在编译时被静态分配在堆栈上,并将地址传递给指针 p。类似于静态数组的分配方式。我对此有 90% 的把握,但一些确认会有所帮助。

谢谢。

【问题讨论】:

  • 你用的是什么编译器?兼容的编译器应该拒绝这个。
  • p 的类型应该是 char const *,因为那段数据(“通常”)是不可写的,现在大多数编译器都会发出警告。
  • @Dani 不,他们不应该。这是完全正常的标准 C 和 C++。
  • @cnicutar: 字符串字面量应该是const char *,所以这一行应该是assignment discards qualifiers的错误。
  • @Dani: 不。在 C++03 和之前有从 char const*char* 的自动转换(允许与 C 向后比较)。我认为这在 C++11 中已被弃用。但大多数编译器都会产生警告。

标签: c++ c memory pointers


【解决方案1】:

您有一个字符串文字 "I didn't malloc..." 位于只读内存中的某处(正是实现定义的位置),它由指针 p 指向。

需要注意的重要一点是,任何更改此字符串文字的尝试都会导致未定义行为

事实上,在 C++ 中,不建议像您那样声明字符串文字。
因此,在 C++ 中,您应该使用 const 限定符,例如:

const char *p = "I didn't malloc...";

【讨论】:

    【解决方案2】:

    这是一个字符串文字。该标准不知道“堆栈”、“堆”等——这些是实现细节。所以没有“标准”位置。

    通常它不在堆栈中。它位于名为text 的只读区域中。而且它不是“类似于静态数组的分配方式”。

    【讨论】:

    • Unix 上名为data 的区域不是只读的。现在,只读数据通常在text 段中,不是吗?
    • @JonathanLeffler 你当然是对的。 data 用于可写初始化的东西。
    【解决方案3】:

    内存也是只读分配的,任何更改 *p 的尝试都是未定义的。
    虽然一般不在堆栈上,但它会是可执行文件数据段的一部分

    【讨论】:

      【解决方案4】:

      字符串文字 "I didn't malloc..." 存储在数据段的只读区域中,p 包含该位置的地址。

      【讨论】:

        【解决方案5】:

        p 将指向将在堆栈上分配的只读内存区域。 此外,编译器会自动在字符串末尾添加一个 '\0' 字节。

        不使用 const 很危险,实际上 g++ 编译器会针对以下代码发出警告:

        #include <stdio.h>
        
        int main(int argc, const char *argv[])
        {
            char *p = "AString8";
            printf("%s\n", p);
            printf("Last char: %c hex: %x\n", p[7], p[7]);
            printf("Last char + 1: %c hex: %x\n", p[8], p[8]);
            return 0;
        }
        

        警告:不推荐将字符串常量转换为‘char*’

        程序输出:

        Last char: 8 hex: 38
        
        Last char + 1:  hex: 0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-05-16
          • 2014-05-10
          • 2020-04-26
          • 2010-12-13
          • 2013-04-23
          • 2015-04-09
          相关资源
          最近更新 更多