成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

【C++】內存中的字符串

開發 后端
前文 內存中的字符串類型 學習研究了Go的字符串在內存中的結構和數據類型。文本是兩年多前的一篇學習筆記,研究的是C++字符串在內存中的結構。

[[422277]]

前文 內存中的字符串類型 學習研究了Go的字符串在內存中的結構和數據類型。

文本是兩年多前的一篇學習筆記,研究的是C++字符串在內存中的結構。

環境

  1. 1. 操作系統:Ubuntu 16.04。 
  2. 2. 調試軟件:GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1。 
  3. 3. 編譯工具:g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609。 

string類的定義

string定義在/usr/include/c++/5/bits/stringfwd.h頭文件中,如下:

  1. typedef basic_string<char> string; 

basic_string類的定義通過泛型編程技術實現,詳細定義請參考/usr/include/c++/5/bits/basic_string.h頭文件,看起來非常復雜,具體實現此處并不關心,不再討論。

測試string對象占用內存空間

通過以下代碼可以測試string類對象占用內存空間情況。

  1. // demo.cpp 
  2. #include <string> 
  3. #include <iostream> 
  4.  
  5. int main(int argc, char const *argv[]) 
  6.     using namespace std; 
  7.  
  8.     string s15(15, 'a'); // 字符串長度15 
  9.     string s16(16, 'x'); // 字符串長度16 
  10.      
  11.     cout << "sizeof(string) = " << sizeof(string) << endl; 
  12.     cout << "sizeof(s15) = " << sizeof(s15) << endl; 
  13.     cout << "sizeof(s16) = " << sizeof(s16) << endl; 
  14.  
  15.     return 0; 

因為32位和64位可執行程序不同,以下將分別編譯測試。

將以上代碼編譯成32位可執行程序并執行,結果如下:

  1. $ g++ -m32 -g demo.cpp 
  2. $ ./a.out  
  3. sizeof(string) = 24 
  4. sizeof(s15) = 24 
  5. sizeof(s16) = 24 

從以上輸出結果,可以十分確定string類對象在內存中占用24個字節。

將以上代碼編譯成64位可執行程序并執行,結果如下:

  1. $ g++ -m64 -g demo.cpp 
  2. $ ./a.out 
  3. sizeof(string) = 32 
  4. sizeof(s15) = 32 
  5. sizeof(s16) = 32 

從以上輸出結果,可以十分確定string類對象在內存中占用32個字節。

32位可執行程序string對象的內存分配

為了查看內存分配,需要用到動態調試工具,此處使用gdb,并在源碼16行設置斷點。

調試過程中,打印main方法的棧數據,以及string對象及相關數據的內存,可以清晰看到string對象數據的內存占用情況。

  1. $ gdb a.out  
  2. GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1 
  3. Reading symbols from a.out...done. 
  4. (gdb) b 16 
  5. Breakpoint 1 at 0x8048a80: file demo.cpp, line 16. 
  6. (gdb) r 
  7. Starting program: a.out  
  8. sizeof(string) = 24 
  9. sizeof(s15) = 24 
  10. sizeof(s16) = 24 
  11.  
  12. Breakpoint 1, main (argc=1, argv=0xffffced4) at demo.cpp:16 
  13. 16      return 0; 
  14. (gdb) x /24wx $esp  // 以16進制格式打印24個寬度為4字節的main函數堆棧數據(共96個字節) 
  15. 0xffffcdd0:  0x08048790  0x0804a0ed  0x0804a04c  0xffffced4 
  16. 0xffffcde0:  0xffffffff  0x00004a00  0xffffce08  0xffffcdf4 
  17. 0xffffcdf0:  0x0000000f  0x61616161  0x61616161  0x61616161 
  18. 0xffffce00:  0x00616161  0x0804fa10  0x00000010  0x00000010 
  19. 0xffffce10:  0x00000001  0xffffced4  0xffffcedc  0xd0415500 
  20. 0xffffce20:  0xffffce40  0x00000000  0x00000000  0xf7c86637 
  21. (gdb) x /wx &s15    // 打印變量s15的內存地址 
  22. 0xffffcdec:  0xffffcdf4 
  23. (gdb) x /6xw 0xffffcdec // 打印string對象s15占用的24個字節內存數據 
  24. 0xffffcdec:  0xffffcdf4  0x0000000f  0x61616161  0x61616161 
  25. 0xffffcdfc:  0x61616161  0x00616161 
  26. (gdb) x /s 0xffffcdf4   // string對象s15的1-4個字節是一個指向字符數據的指針 
  27. 0xffffcdf4:  'a' <repeats 15 times> 
  28. (gdb) x /16x 0xffffcdf4 // string對象s15的9-24個字節是代表數據的字符數組 
  29. 0xffffcdf4:  0x61  0x61  0x61  0x61  0x61  0x61  0x61  0x61 
  30. 0xffffcdfc:  0x61  0x61  0x61  0x61  0x61  0x61  0x61  0x00 
  31. (gdb) x /wx &s16    // 打印變量s16的內存地址 
  32. 0xffffce04:  0x0804fa10 
  33. (gdb) x /6xw 0xffffce04 // 打印string對象s16占用的24個字節內存數據 
  34. 0xffffce04:  0x0804fa10  0x00000010  0x00000010  0x00000001 
  35. 0xffffce14:  0xffffced4  0xffffcedc 
  36. (gdb) x /s 0x0804fa10  // string對象s16的1-4個字節是一個指向字符數據的指針 
  37. 0x804fa10:  'x' <repeats 16 times> 
  38. (gdb) x /16x 0x0804fa10 
  39. 0x804fa10:  0x78  0x78  0x78  0x78  0x78  0x78  0x78  0x78 
  40. 0x804fa18:  0x78  0x78  0x78  0x78  0x78  0x78  0x78  0x78 
  41. (gdb) c 
  42. Continuing. 
  43. [Inferior 1 (process 20982) exited normally] 
  44. (gdb) q 

從以上調試可以看出,string對象的內存結構和以下結構體的非常相似:

  1. typedef long int u32; 
  2. struct String 
  3.     char *data_ptr; // 指向字符數組的指針,在32位程序占用4個字節 
  4.     u32 length;     // 字符數組的長度,在32位程序占用4個字節 
  5.     char data[16];  // 可以容納15個字符的數組,占用16個字節 
  6. }; 

1.string對象的1-4個字節是一個指向字符數據的指針。

2.string對象的5-8個字節是一個表示字符數據長度的整形數值。

3.string對象的9-24個字節的含義根據字符數據的長度發生變化。

  • 如果string對象包含的字符數組長度小于16,則將字符數據保存在string對象本身所占用的內存中;以上述結構體String為例,將字符數據保存在data中。
  • s15.data_ptr == &(s15.data[0]);
  • 如果string對象包含的字符數組長度大于等于16,則其字符數據位于可執行文件的數據區或分配到堆內存中,而不是棧內存中;以上述結構體String為例,無法將字符數據保存在data字段中。

64位可執行程序string對象的內存分配

64位程序與32位程序非常相似,只不過64程序中,指針對象占用8字節內存;通過動態調試,發現內存分配與以下結構體非常相似:

  1. typedef long long int u64; 
  2. struct String 
  3.     char *data_ptr; // 指向字符數組的指針,在64位機器占用8個字節 
  4.     u64 length;     // 字符數組的長度,在64位機器占用8個字節 
  5.     char data[16];  // 可以容納15個字符的數組,占用16個字節 
  6. }; 

以上內容是兩年多前的學習筆記,最近在以下環境中進行測試,得到的結論與上述內容一致。

  1. 操作系統:Ubuntu 20.04。 
  2. 調試軟件:GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2。 
  3. 編譯工具:g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0。 

本文轉載自微信公眾號「Golang In Memory」

 

責任編輯:姜華 來源: Golang In Memory
相關推薦

2021-07-30 06:22:37

C++字符型字符串

2010-02-04 17:32:43

C++中C風格字符串

2023-12-11 15:18:03

C++字符串Unicode

2024-02-22 09:46:04

C++字符串格式化開發

2010-02-02 11:27:16

C++字符串

2021-08-20 06:58:31

C++Python函數

2021-09-10 08:18:31

Go語言字符串

2012-01-11 09:15:45

Objective-C

2010-02-04 17:39:48

C++字符串類型

2024-03-11 06:05:00

C++字符串

2010-02-01 16:46:07

C++格式化字符串

2024-04-01 08:41:39

字符串.NET

2010-02-02 18:01:47

C++字符串替換函數

2011-06-16 09:28:02

C++內存泄漏

2023-11-17 11:40:51

C++內存

2011-05-25 09:58:46

C#

2013-05-02 11:13:05

C++遇到iOS應用開字符串處理

2023-10-25 13:27:20

C++字符串

2010-02-04 10:52:36

C++字符串分割函數

2011-07-15 01:10:13

C++內存分配
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产在线观看不卡一区二区三区 | 国产成人精品一区二区三 | 99视频在线播放 | 亚洲一区二区三区四区五区午夜 | 羞羞网站在线免费观看 | 看亚洲a级一级毛片 | 成年人黄色免费视频 | 精品国产一区二区在线 | 国产精品一区二区欧美黑人喷潮水 | 国产99热精品 | 亚洲小视频在线观看 | 免费黄色片在线观看 | 久久久久久一区 | 日本特黄a级高清免费大片 成年人黄色小视频 | 成人免费精品视频 | 国产亚洲久 | 超碰操| 亚洲精品日日夜夜 | 国产成人精品免高潮在线观看 | 99re视频这里只有精品 | 日韩成人中文字幕 | 激情黄色在线观看 | 国产区在线观看 | 91精品国产色综合久久不卡98 | 中文字幕免费视频 | 在线观看免费国产 | 青青草原综合久久大伊人精品 | av午夜激情 | 日韩国产欧美视频 | 国产色片在线 | 欧美中国少妇xxx性高请视频 | 中文字幕乱码一区二区三区 | 亚洲乱码一区二区三区在线观看 | 欧美一级片免费看 | 国内自拍第一页 | 亚洲成人综合网站 | 久久久久久久久淑女av国产精品 | 国产精品视频在线播放 | www.9191.com| 亚洲精品久久 | 久久综合九色综合欧美狠狠 |