Kg

63 阅读3分钟

1 大小端

#include <iostream>
using namespace std;

int main() {
    unsigned int a = 0x12345;
    unsigned char b = *(unsigned char*)&a;
    cout << b << endl;
}

这是因为在大多数计算机体系结构中,多字节整数(如 unsigned int)的存储方式是以小端序(Little-Endian)或大端序(Big-Endian)的形式存储的。在小端序系统中,最低有效字节(低字节)存储在内存中的最低地址处,因此通过强制类型转换和解引用,你获取到的是 0x1234 中的 0x34,这就是为什么输出了低字节的原因。

image.png

#include <iostream>
using namespace std;

int main() {
    int a = 0x1234;
    // 由于int和char的长度不同,借助int型转换成char型,只会留下低地址的部分
    char c = static_cast<char>(a);

    if (c == 0x12) {
        cout << "big endian" << endl;
    } else if (c == 0x34) {
        cout << "little endian" << endl;
    }

    return 0;
}

2 迭代器失效

插入元素后end操作返回的迭代器失效

问题描述:在使用push_back插入元素后,end()操作返回的迭代器失效。

解决方法:为了解决这个问题,可以使用迭代器插入操作,而不是push_back。例如,使用insert函数可以插入元素,并返回新元素的迭代器位置。

插入元素后可能需要扩容,导致已有迭代器失效

问题描述:使用push_back插入元素后,如果vector需要扩容,会导致已有迭代器全部失效。

解决方法:为了解决这个问题,可以在插入元素之前使用reserve函数来预分配足够的内存空间,以减少扩容的次数。这样可以避免大部分迭代器的失效。

删除操作后迭代器失效

问题描述:使用erasepop_back删除元素后,指向删除点及其后的元素的迭代器都会失效。

解决方法:为了解决这个问题,可以使用erase函数返回的迭代器,它指向被删除元素的下一个元素。另外,可以考虑使用eraseremove_if等算法来避免手动删除元素。

3.指针失效

std::vector仅调用push_back方法时,指向该vector元素的指针通常不会失效。这是因为push_back通常只会在vector的末尾添加新元素,而不会涉及重新分配内存或改变已有元素的位置。

但是,需要注意以下几点:

  1. std::vectorsize达到其容量(capacity)时,可能会触发内部的重新分配操作,这将导致指向vector元素的指针和迭代器失效。重新分配会为vector分配更大的内存块,并将元素从旧内存复制到新内存,此时之前的指针和迭代器会失效。因此,在追加大量元素时,可能会发生重新分配,需要注意。
  2. 如果在push_back之后进行inserterasepop_back等操作,这些操作可能会导致vector内部元素的重新排列,从而使指针和迭代器失效。
  3. 要确保指针不失效,可以使用索引访问元素而不是指针,或者在可能触发重新分配的情况下,使用reserve来提前分配足够的内存以减少重新分配的发生。

4. 宏定义

这段代码主要是在宏定义中使用了预处理指令,用于生成一个版本号字符串,并将其打印出来。让我们逐步解释:

image.png

5.内存分配

image.png