C++字符串变量、字符串常量、string变量在内存中的存储分析

本文详细阐述了C++中字符串常量与变量的内存布局,包括它们如何在栈区、堆区及静态存储区中存储。同时介绍了string类型变量的特点及其在内存中的表现形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++中内存布局,内存地址:栈区>堆区>静态存储区

一、字符串常量和字符串变量

我们知道字符串常量是存储在文字常量区,也即C++中的静态存储区。

而字符串变量一般定义在栈区,当使用malloc时则定义在堆区。

  char* ss = "hello world";
  printf("%p\n", &ss); //字符串变量ss的存储地址(变量声明的地址)
  printf("%c: %p\n", ss[0],  &(ss[0]));//字符串变量ss中第一个字符h的存储地址
  printf("%c: %p\n", ss[1],  &(ss[1]));//字符串变量ss中第二个字符e的存储地址
  printf("%p\n", &"hello world");//字符串常量的首地址
  printf("%p\n", &("hello world"[0]));//字符串常量第一个字符h的存储地址
  printf("%p\n", &("hello world"[1]));//字符串常量第二个字符e的存储地址
  /*
  0x7fffecff31b8 栈区
  h: 0x401420    静态存储区
  e: 0x401421    静态存储区
  0x401420       静态存储区
  0x401420       静态存储区
  0x401421       静态存储区
  */

/*用malloc申请内存*/
  char* ss = (char*)malloc(128);
  memset(ss, 0, 128);
  strcpy(ss, "hello world");
  printf("%p\n", &ss); //字符串变量ss的存储地址(变量声明的地址)
  printf("%c: %p\n", ss[0],  &(ss[0]));//字符串变量ss中第一个字符h的存储地址
  printf("%c: %p\n", ss[1],  &(ss[1]));//字符串变量ss中第二个字符e的存储地址
  printf("%p\n", &"hello world");//字符串常量的首地址
  printf("%p\n", &("hello world"[0]));//字符串常量第一个字符h的存储地址
  printf("%p\n", &("hello world"[1]));//字符串常量第二个字符e的存储地址
  /*
  0x7ffc38cae008   栈区
  h: 0x628130      堆区
  e: 0x628131      堆区
  0x401470         静态存储区
  0x401470         静态存储区
  0x401471         静态存储区
  */
  1. 字符串变量存储在静态存储区;
  2. 在栈区声明一个字符串变量,char* ss = "hello world";这句代码会将栈区变量ss指向静态存储区的字符串,因此访问栈区ss变量时,是访问了静态存储区的"hello world"。
  3. 在栈区声明一个字符串变量,char* ss = (char*)malloc(128);这行代码在堆区申请了一块128字节的内存,并将栈区变量ss指向这块堆内存,strcpy(ss, "hello world");则将静态存储区的字符串拷贝至堆区。

其他需要注意的点:

我们在栈区char* ss时,只是在栈区声明了一个字符串变量,如果想使用strcpy拷贝字符串,则目的地址必须是申请的堆空间字符串变量地址,或者是栈空间的字符数组。
//  char* ss;
//  strcpy(ss, "hello world");//错误,不能讲常量字符串拷贝至一个字符串变量,因为该字符串变量没有申请空间存储

  char ss[128];
  memset(ss, 0, 128);
  strcpy(ss, "hello world");//正确,ss是栈空间的字符数组

 

二、string变量

string是C++定义的类,在其实现中,数据内容存储在堆空间中,在对象析构时将会释放其申请的堆内存,还要注意的是使用string的“+”运算符等时,拼接到一起的字符串其地址空间可能是不连续的。

  string tmpstr = "hello world";
  printf("tmpstr: %p\n", &tmpstr);//string变量tmpstr的存储位置
  printf("%c %p\n", tmpstr[0],  &(tmpstr[0]));//tmpstr变量中字符串第一个字符h存储的位置
  printf("%c %p\n", tmpstr[1],  &(tmpstr[1]));//tmpstr变量中字符串第二个字符e存储的位置
  printf("%c %p\n", tmpstr[10],  &(tmpstr[10]));//tmpstr变量中字符串第11个字符d存储的位置

  tmpstr += "123";//拼接一段字符串

  printf("%c %p\n", tmpstr[11],  &(tmpstr[11]));//拼接后的tmpstr第12个字符1存储的位置
  printf("%c %p\n", tmpstr[12],  &(tmpstr[12]));//拼接后的tmpstr第13个字符2存储的位置
  printf("%p\n", &"hello world");//"hello world"字符串首地址
  printf("%p\n", "hello world");

  /*
   tmpstr: 0x7ffe73dbd690 栈区
    h 0x9bf028            堆区
    e 0x9bf029
    d 0x9bf032
    1 0x9bf063
    2 0x9bf064
    0x400d20              静态存储区
    0x400d20
   */

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值