Char Array VS Char *

Char Array VS Char *

本文关键字:Char Array VS      更新时间:2023-10-16

这是一个基于下列问题的答案的问题:

const char myVar*与const char myVar[]

const char* x = "Hello World!";
const char  x[] = "Hello World!";

我现在明白了区别,但我的新问题是:

(1)如果我重新赋值x,第一行的"Hello World"字符串会发生什么?到那时,没有任何东西指向它——当作用域结束时,它会被销毁吗?

(2)除了const-ness之外,编译器在内存中存储两个示例中的值有什么不同?

在代码中放置"Hello World!"会导致编译器在编译后的可执行文件中包含该字符串。当程序执行时,这个字符串在调用main之前在内存中创建,我相信,甚至在调用__start之前(这是静态初始化器开始运行的时候)。char * x的内容不是通过newmalloc分配的,也不是在main的堆栈帧中分配的,因此不能取消分配。

然而,在函数或方法中声明的char x[20] = "Hello World"是在堆栈上分配的,当在作用域中时,实际上在内存中会有两个"Hello World"的副本-一个预加载了可执行文件,一个在堆栈分配的缓冲区中。

编译器将第一个数据存储在称为RODATA(只读数据)的内存段中。只要程序还在运行,内存就保持它的初始值。

第二个数组和其他数组一样存储在堆栈中。就像任何其他局部变量一样,它可以在其作用域结束时被覆盖。

    在这两种情况下,"Hello World!"字符串都是作为char的连续序列在静态内存中分配的,所以没有动态分配的内存可以回收,也没有任何类实例可以销毁;
  1. 两个x都将在静态内存或堆栈中分配,这取决于它们的定义位置。然而,指针将被初始化为指向相应的"Hello World!"字符串,而数组将通过直接复制字符串字面值来初始化。

理论上,当没有办法访问这两个字符串字面值时,编译器可以自由地回收它们的内存;实际上,第一个内存不太可能被回收,因为通常静态内存会一直分配给程序,直到程序终止;另一方面,如果数组是在堆栈上分配的,那么第二个数组甚至可能根本不被分配,因为编译器可能会使用其他方法来确保数组被正确初始化,并且当数组超出作用域时,数组内存将被回收。