c++面试2

一 、 char类型数组转换成字符串的方法

  1. 使用 std::string 构造函数: 可以使用 std::string 类的构造函数直接将 C 风格字符串转换为 std::string 对象,例如:std::string str(buf);

    const char* buf = "Hello, world!"; // C 风格字符串
    std::string str(buf); // 使用构造函数将其转换为 std::string 对象
    
  2. 使用赋值操作符: 可以使用 std::string 对象的赋值操作符将 C 风格字符串赋值给 std::string 对象,例如:str = buf;

    const char* buf = "Hello, world!"; // C 风格字符串
    std::string str; // 初始化一个空的 std::string 对象
    str = buf; // 使用赋值操作符将 C 风格字符串赋值给 std::string 对象
    
  3. 使用 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扩容机制

面试题:C++vector的动态扩容,为何是1.5倍或者是2倍_vector扩容1.5倍,2倍区别-CSDN博客

STL之vector扩容机制 - 知乎 (zhihu.com) 

补充:

选择以1.5倍或2倍方式进行扩容是为了平衡内存的使用效率和空间利用率。

  1. 效率考虑: 扩容时,如果选择将容量翻倍(即乘以2),这意味着每次扩容后,剩余的空间仍然是原来的一半,这样做的好处是可以保证插入操作的平摊时间复杂度为 O(1)。如果选择以更小的倍数(比如1.5倍),虽然可以减少内存的浪费,但会增加频繁扩容的次数,导致插入操作的时间复杂度增加。

  2. 空间利用率考虑: 扩容时,选择以2倍方式进行扩容可以保证空间的利用率相对较高。虽然每次扩容会多分配一些空间,但是由于每次扩容后的空间是原来的两倍,所以在一定程度上可以减少内存分配和释放的次数,提高了内存的使用效率。

        总的来说,以1.5倍或2倍方式进行扩容可以在内存利用率和插入操作的效率之间找到一个较好的平衡点。虽然这样做可能会略微增加内存的浪费,但能够提高插入操作的性能,同时也保证了相对较高的空间利用率。

四、brk()和mmap分配内存原理:

操作系统--brk()和mmap()详解_brk和mmap-CSDN博客

Linux内存分配小结--malloc、brk、mmap_mmap申请的内存和堆内存有什么区别-CSDN博客

五、伙伴系统 

        在内核初始化完成之后, 内存管理的责任就由伙伴系统来承担. 伙伴系统基于一种相对简单然而令人吃惊的强大算法.

        Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Knowlton设计, 后来Knuth又进行了更深刻的描述.
        伙伴系统是一个结合了2的方幂个分配器和空闲缓冲区合并计技术的内存分配方案, 其基本思想很简单. 内存被分成含有很多页面的大块, 每一块都是2个页面大小的方幂. 如果找不到想要的块, 一个大块会被分成两部分, 这两部分彼此就成为伙伴. 其中一半被用来分配, 而另一半则空闲. 这些块在以后分配的过程中会继续被二分直至产生一个所需大小的块. 当一个块被最终释放时, 其伙伴将被检测出来, 如果伙伴也空闲则合并两者.

工作原理
  1. 内存块划分:

    • 将可用内存划分为一系列大小相等的块,每个块的大小通常是2的幂次方,例如1KB、2KB、4KB等。
    • 每个块都有一个伙伴块,其大小也是2的幂次方,即两个块大小之和为2的幂次方。
  2. 内存分配:

    • 当进程需要分配内存时,系统会搜索可用块链表,找到最小可用块大小能够满足分配请求的块。
    • 如果找到的块大小正好等于请求的大小,则直接将该块分配给进程。
    • 如果找到的块大小大于请求的大小,则将该块分割成两个等大小的伙伴块,其中一个分配给进程,另一个留作后续分配使用。
  3. 内存释放:

    • 当进程释放内存时,系统会将该内存块标记为空闲状态,并尝试与其伙伴块合并。
    • 如果释放的块的伙伴块也是空闲的,则两个块会被合并成一个更大的块。
    • 合并后的块会继续尝试与其它空闲块合并,直到无法再合并为止。
  4. 合并策略:

    • 合并过程通过二进制的方式实现,即两个相同大小的伙伴块可以通过将它们的二进制表示向左移动一位来合并成一个更大的块。
  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值