一 、 char类型数组转换成字符串的方法
-
使用
std::string
构造函数: 可以使用std::string
类的构造函数直接将 C 风格字符串转换为std::string
对象,例如:std::string str(buf);
。const char* buf = "Hello, world!"; // C 风格字符串 std::string str(buf); // 使用构造函数将其转换为 std::string 对象
-
使用赋值操作符: 可以使用
std::string
对象的赋值操作符将 C 风格字符串赋值给std::string
对象,例如:str = buf;
。const char* buf = "Hello, world!"; // C 风格字符串 std::string str; // 初始化一个空的 std::string 对象 str = buf; // 使用赋值操作符将 C 风格字符串赋值给 std::string 对象
-
使用
assign()
函数: 可以使用assign()
函数将字符序列分配给std::string
对象,例如:str.assign(buf);
。const char* buf = "Hello, world!"; // C 风格字符串 std::string str; // 初始化一个空的 std::string 对象 str.assign(buf); // 使用 assign() 函数将字符序列分配给 std::string 对象
二、字符串转字符数组的方法
将 C++ 中的 std::string
转换为字符数组(C 风格字符串),可以使用 c_str()
函数。该函数返回一个以空字符结尾的字符数组,表示 std::string
中的内容。这个字符数组是 const char*
类型的指针,所以不能直接修改其中的内容。
#include <iostream>
#include <string>
int main() {
std::string str = "Hello, world!";
// 使用 c_str() 函数将 std::string 转换为 C 风格字符串
const char* cstr = str.c_str();
// 输出转换后的 C 风格字符串
std::cout << "C-style string: " << cstr << std::endl;
return 0;
}
三、vector扩容机制
补充:
选择以1.5倍或2倍方式进行扩容是为了平衡内存的使用效率和空间利用率。
-
效率考虑: 扩容时,如果选择将容量翻倍(即乘以2),这意味着每次扩容后,剩余的空间仍然是原来的一半,这样做的好处是可以保证插入操作的平摊时间复杂度为 O(1)。如果选择以更小的倍数(比如1.5倍),虽然可以减少内存的浪费,但会增加频繁扩容的次数,导致插入操作的时间复杂度增加。
-
空间利用率考虑: 扩容时,选择以2倍方式进行扩容可以保证空间的利用率相对较高。虽然每次扩容会多分配一些空间,但是由于每次扩容后的空间是原来的两倍,所以在一定程度上可以减少内存分配和释放的次数,提高了内存的使用效率。
总的来说,以1.5倍或2倍方式进行扩容可以在内存利用率和插入操作的效率之间找到一个较好的平衡点。虽然这样做可能会略微增加内存的浪费,但能够提高插入操作的性能,同时也保证了相对较高的空间利用率。
四、brk()和mmap分配内存原理:
操作系统--brk()和mmap()详解_brk和mmap-优快云博客
Linux内存分配小结--malloc、brk、mmap_mmap申请的内存和堆内存有什么区别-优快云博客
五、伙伴系统
在内核初始化完成之后, 内存管理的责任就由伙伴系统来承担. 伙伴系统基于一种相对简单然而令人吃惊的强大算法.
Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Knowlton设计, 后来Knuth又进行了更深刻的描述.
伙伴系统是一个结合了2的方幂个分配器和空闲缓冲区合并计技术的内存分配方案, 其基本思想很简单. 内存被分成含有很多页面的大块, 每一块都是2个页面大小的方幂. 如果找不到想要的块, 一个大块会被分成两部分, 这两部分彼此就成为伙伴. 其中一半被用来分配, 而另一半则空闲. 这些块在以后分配的过程中会继续被二分直至产生一个所需大小的块. 当一个块被最终释放时, 其伙伴将被检测出来, 如果伙伴也空闲则合并两者.
工作原理
-
内存块划分:
- 将可用内存划分为一系列大小相等的块,每个块的大小通常是2的幂次方,例如1KB、2KB、4KB等。
- 每个块都有一个伙伴块,其大小也是2的幂次方,即两个块大小之和为2的幂次方。
-
内存分配:
- 当进程需要分配内存时,系统会搜索可用块链表,找到最小可用块大小能够满足分配请求的块。
- 如果找到的块大小正好等于请求的大小,则直接将该块分配给进程。
- 如果找到的块大小大于请求的大小,则将该块分割成两个等大小的伙伴块,其中一个分配给进程,另一个留作后续分配使用。
-
内存释放:
- 当进程释放内存时,系统会将该内存块标记为空闲状态,并尝试与其伙伴块合并。
- 如果释放的块的伙伴块也是空闲的,则两个块会被合并成一个更大的块。
- 合并后的块会继续尝试与其它空闲块合并,直到无法再合并为止。
-
合并策略:
- 合并过程通过二进制的方式实现,即两个相同大小的伙伴块可以通过将它们的二进制表示向左移动一位来合并成一个更大的块。