拜托,我想知道变量,数组和字符串如何用C语言存储在内存中的现实。请在下面的例子中纠正我对记忆的理解:
在C中,当我们声明一个字符串时,我们按以下步骤继续:
char string[]="string";
记忆中会发生什么?每个字符都存储在一个内存的情况下 每个内存都有它的地址?
例如,地址
1600 char[0]='S'
1602 char[2]='t'
等等。这是真的?如果没有,请给我一个关于真实情况的正确模式。
我的第二个问题是关于C ++:
在C ++中,他们发明了一种新的数据类型string
。例如:
string variable("This is a string");
该文本(“这是一个字符串”)如何存储在内存中?
答案 0 :(得分:3)
[...] C ++标准未定义字符串类的内存布局的确切实现。该体系结构旨在足够灵活,允许编译器供应商进行不同的实现,同时保证用户可预测的行为。 [...]
[...]在C ++中,单个字符串对象可能会占用内存的唯一物理区域,也可能不会占用内存的唯一物理区域,但如果使用引用计数来避免存储重复的数据副本,则各个对象的外观和行为必须像它们一样独家拥有独特的存储区域。 [...]
您可以通过以下方式了解编译器如何实现string
。对我来说(在VS2010下测试),它将是
string variable("This is a string");
printf("%p\n", &variable[0]); // 006751C0
printf("%p\n", &variable[1]); // 006751C1
printf("%p\n", &variable[2]); // 006751C2
printf("%p\n", &variable[3]); // 006751C3
printf("%p\n", &variable[4]); // 006751C4
printf("%p\n", &variable[5]); // 006751C5
... ...
答案 1 :(得分:2)
String都存储为以null结尾的char数组(ASCII代码中的每个char都是8位宽,这样它只占用一个字节),因此需要多一个字节来存储'\ 0'字符( “hi”需要一个三个字节的数组) 如果你在c ++中使用std :: string,那么用于存储数据的内存是相同的,但是在它周围有一个允许自动内存管理的包装器,所以当你这样做时:
string s("hello");
string t("world");
s+=t;
如果为了找到更长的连续字节数组,s被扩展或甚至移动到内存中的其他位置。 当你打电话的时候也是这样的
s.c_str();
你得到一个指向包含在s std :: string类实例中的空终止数组的指针,该指针只是一个临时指针,所以这个
char* text=s.c_str();
s="very long string that probably results in a complete reallocation of the array";
printf("%s",text);
可能会导致未定义的行为(分段错误)
答案 2 :(得分:0)
它们以字节的形式存储:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double : 8 bytes
答案 3 :(得分:0)
每次构建(编译和链接)项目时,都会创建一个可执行映像,分为三个部分:
代码段
数据部分
堆栈
场景#1 - 本地数组(在函数内声明):
int func()
{
char array[]="string";
...
}
加载并运行程序后,每次调用该函数时,位于堆栈某处的7个字节都会使用以下值进行初始化:'s','t','r','i' ,'n','g',0 。这些字节所在的堆栈上的地址是调用该函数时SP寄存器的值。因此,每次调用函数时,这7个字节可能驻留在内存中的不同地址中。
场景#2 - 全局数组(在函数外声明):
char array[]="string";
在编译期间( 之前加载并运行程序),数据部分中的7个字节设置为以下值:'s','t','r' ,'我','n','g',0 。这些字节被“硬编码”到可执行映像中,一旦它被加载到内存中(即,无论何时运行程序),它们都会在程序执行期间驻留在同一地址中。
场景#3 - 指向本地数组的指针(在函数内声明):
int func()
{
char* array="string";
...
}
与场景#2相同,除了这7个字节位于代码段(只读部分),而不是数据部分(读/写部分) 。此外,指针(array
)在堆栈上分配并在每次调用函数时初始化(设置为指向代码段中的"string"
的地址)。使用32位RAM时,该指针的大小通常为4个字节;使用64位RAM时,该指针的大小通常为8个字节。
场景#4 - 指向全局数组的指针(在函数外声明):
char* array="string";
与场景#3相同,除了指针(array
)位于数据部分而不是堆栈中并初始化一次(编译期间)而不是每次调用函数时(执行期间)。