【问题标题】:Memory Allocation char* and char[]内存分配 char* 和 char[]
【发布时间】:2011-06-08 12:03:26
【问题描述】:

这两者在内存分配方面有什么区别。

char *p1 = "hello"; 
char p2[] = "hello";

【问题讨论】:

  • 第一个应该是const char*!
  • p1 占用 4 或 8 个字节(存储内存地址所需),这取决于平台。 p2 占用 6 个字节(= 5 个字节用于字符串 hello + 1 个字节用于空终止字符)。

标签: c++


【解决方案1】:

第一个创建一个 pointer 变量(4 或 8 个字节的存储空间,具体取决于平台)并在那里存储字符串文字的 location,第二个创建array 六个字符(包括零字符串终止字节)并在那里复制文字。

您应该在第一行收到编译器警告,因为文字是 const

【讨论】:

  • 字符串文字究竟存储在哪里?它在堆中吗?
  • 字符串文字通常存储在与堆栈和(new/delete-managed)堆分开的内存区域中。根据您的平台,该区域可能受到复制保护,因此写入该区域会使程序崩溃。
  • 如果我没记错的话p2 也不过是一个指针变量。不是吗?因此,在p2 的情况下也应该分配四个或八个字节的存储空间,具体取决于平台。这段代码p1 = p2; printf("%c" , *(p1 + 4)); 打印o。所以剩下的唯一区别是在声明p2的情况下有一个空终止字符。
【解决方案2】:

第一个是指向 const(只读)数据的非常量指针,第二个是非常量数组。

【讨论】:

  • @Mahatma:是的,这也与更易读和直观的版本相同:const char *p1 = "hello"
  • @Mahatma:是的,但第一个是危险的:没有const 资格,没有编译器保护,防止试图修改字符串文字,给出未定义的行为。
  • @RBT:是的,字符串字面量初始化程序保证了这一点。
  • 好的。凉爽的。所以这意味着asker发布的两个代码块在分配的字节数(字符串占用的内存+空终止字符)上绝对没有差异,并且都有一个指针变量,每个变量都指向分配的字符串的开始。您建议的差异是目标。我无法彻底消化该线程上已接受的答案。我来自 C# 背景,无法区分字符串文字(只读 const 事物)和字符数组 :(.
  • 你明白了! ;-)
【解决方案3】:

由于第一个是指向 const(只读)数据的非常量指针,所以第二个是非常量数组,正如 Paul 所说,可以这样写:

p2[2]='A'; //changing third character - okay

但你不能写:

p1[2]='A';//changing third character - runtime error!

【讨论】:

  • 第二种情况其实比编译错误还要糟糕;编译器很可能会接受它,给出未定义的运行时行为。
  • 这不是真的——他不会得到编译错误,因为字符串文字不是 const。然而,他将获得 UB。
  • 这不是固定的。该代码产生 UB,这不是运行时错误。这是未定义的行为。现在,实际上在大多数平台上,您都会收到运行时错误(Unix 变体上的 SIGSEGV,Windows 上的访问冲突)。然而,标准对此只字未提,因为他没有提到他的平台,所以你不能假设。
  • @Nawaz 在 p1 和 p2 声明的情况下会有空终止字符吗? 是否会根据平台额外分配 4 或 8 个字节的存储空间在 p2 的情况下也会发生(与 p1 相同),因为 p2 最终也是一个指针?
  • @RBT: 说"指向p1的只读字符串字面量"的内存是@的一部分在技术上是错误 987654324@。举个例子,char const *x = "Rasik"; char const *y = "Rasik";。现在打印xy的地址;它们将相同(请参阅demo)。那是什么意思?您不能"Rasik" 是分配给xy 的内存的一部分。 错了"Rasik" 是一个不同的对象.... 并且xy 指向 那个 对象。可以有更多的指针指向同一个对象。现在有意义吗?
猜你喜欢
  • 1970-01-01
  • 2016-07-31
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
  • 2015-09-25
  • 2019-01-10
  • 2023-03-15
相关资源
最近更新 更多