Memory Allocation char* and char[]
这两者在内存分配方面的区别是什么?
1 2
| char *p1 ="hello";
char p2[] ="hello"; |
- 第一个应该是const char*!
- p1采用4或8字节(存储内存地址所需),这取决于平台。p2取6个字节(字符串hello取5个字节,空终止字符取1个字节)。
第一个创建一个指针变量(4或8字节的存储空间取决于平台),并在其中存储一个字符串文本的位置;第二个创建一个包含6个字符(包括零字符串终止符字节)的数组,并在其中复制该文本。
您应该在第一行得到一个编译器警告,因为文本是const。
- 字符串文本存储在哪里?它在堆里吗?
- 字符串文字通常存储在与堆栈和(new/delete托管)堆分开的内存区域中。根据平台的不同,此区域可能受到复制保护,因此写入该区域将导致程序崩溃。
- 非常感谢你给我清晰的答案。
- 如果我没有错,p2也只是一个指针变量。不是吗?因此,在p2的情况下,也应该根据平台分配4或8字节的存储。这段代码p1 = p2; printf("%c" , *(p1 + 4));打印o。所以唯一的区别是声明p2时有一个空终止字符。
第一个是指向常量(只读)数据的非常量指针,第二个是非常量数组。
- 那么char*p1="hello"等同于char const*p1="hello"吗?
- @圣雄主义:是的,这和更易读、更直观的版本一样:const char *p1 ="hello"。
- @Mahatma:是的,但是第一个是危险的:如果没有const的限定,就没有编译器保护来防止试图修改字符串文字,给出未定义的行为。
- 如果同时声明p1和p2,是否有一个空终止字符?
- @RBT:是的,字符串文字初始化器保证了这一点。
- 好啊。酷。因此,这意味着asker发布的两个代码块在分配的字节数(字符串占用的内存+空终止字符)上完全没有差异,并且都有一个指针变量,每个变量都指向分配的字符串的开头。你所建议的不同点是目标明确。我无法完全理解这条线索上被接受的答案。我来自C背景,无法区分字符串文字(只读常量thingy)和字符数组:()。
- 你明白了!;-)
由于第一个是指向const(只读)数据的非常量指针,第二个是非常量数组,正如Paul所说,您可以编写:
1
| p2[2]='A'; //changing third character - okay |
但你不能写:
1
| p1[2]='A';//changing third character - runtime error! |
- 第二种情况实际上比编译错误更糟;编译器很可能会接受它,给出未定义的运行时行为。
- 这不是真的-他不会得到编译错误,因为字符串文字不是常量。但是他会得到UB。
- @死区:固定。:-)
- 那不是固定的。该代码生成ub,这不是运行时错误。这是未定义的行为。现在,实际上在大多数平台上,您将得到一个运行时错误(Unix变体上的sigsegv,Windows上的访问冲突)。然而,标准没有提到这个问题,因为他没有提到他的平台,所以你不能假设它。
- @在p1和p2声明的情况下,nawaz会有一个空终止字符吗?另外,在p2(与p1相同)的情况下,是否还会根据平台额外分配4或8个字节的存储空间,因为p2最后也是一个指针?
- @RBT:1)是的,p1和p2都是空终止。2)p1精确取存储静态数组第一个元素地址(由字符串文字"hello"定义)的sizeof(p1)字节内存。但是,p2是一个数组,而不是一个指针,它是由字符串文字"hello"创建的,它需要sizeof(p2)字节的内存。还要注意,sizeof(p1)和sizeof(p2)可能不同,在这种情况下,它肯定会不同。
- …我还看到了"额外分配"的含义。没有这样的"额外分配"。字符串文字"hello"驻留在其他一些内存中,无论如何它不是p1的一部分。p1正好指向它。只不过如此。如果这澄清了你的疑虑,请告诉我。
- 对。p1的"hello"将驻留在其他一些内存区域,因为它不能在那里进行修改,之后就可以进行堆分配了。我只是想了解在两种情况下消耗的字节数,假设这是控制台C应用程序中唯一的代码行。对于p1-与指针大小相关的字节+字符串为5字节+空终止字符为1字节。对于p2,字符串为5字节,对于空终止字符为1字节。这就是为什么我要说,p1是一个指针会导致额外的内存分配,而p2不是这样,它将被存储在堆栈上。
- @RBT:对于p1,它只是指针的大小(可以是4或8)。没有别的了。对于p2字节,它是6字节。在p1的情况下,没有额外的内存分配。再举一个例子:int x = 10; int *y=&x;。这里,y的大小只是指针的大小(即4或8)。y没有额外/其他分配。
- 我试着按照op来比较,谁问difference between these two in terms of memory allocation,这就是为什么我说p2取6字节(字符数组)和p1(4或8字节作为指针存储内存地址)+p1(6字节)指向的只读字符串。指向存储地址的指针或指向特定程序区域的只读字符串所占用的空间也是内存分配的一种方式。不是吗?或者是我把话说错了。对不起,如果我说的很傻,因为我来自C世界,想学C。
- @RBT:"只读字符串文本指向p1"的内存是p1的一部分,这在技术上是错误的。以这个例子为例,char const *x ="Rasik"; char const *y ="Rasik";。现在打印x和y的地址;它们将是相同的(见演示)。那是什么意思?不能说"Rasik"是分配给x和y的内存的一部分。这是错误的。"Rasik"是另一个对象…以东十一〔17〕和以东十一〔8〕指的是那个目标。可以有更多指针指向同一对象。现在有意义了吗?
- …至于你的背景,我想我知道。我为一级班工作了一个月;)。是的,C.//Java/Python等使得C++的一些概念很难理解。
- @ RBT,@纳瓦兹,他们称C++为困难。线程函数可以是静态的或非静态的(how)。lambda没有捕获规范。C_中没有const。没有什么比不上static_assert—不可能。他们喜欢运行时例外。只剩下1个带1e;)
- AJAY:嗯,C通过简化C++的许多特性而变得简单。C++是最复杂的语言(并且有它的基本原理),这是一个已知的事实。