std::array使用笔记

std::array 是C++标准库中用于封装原生定长数组的模板类,它与原生数组内存大小相同,且默认在栈上分配。相比原生数组,std::array 提供了更多便捷操作,如直接获取大小和快速清零。推荐在元素数量固定的情况下使用。本文将介绍其包含头文件、定义与初始化、使用场景以及字节数组的妙用。

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

概要

std::arrayC++标准库提供的一个封装原生定长数组的模板类

  • std::array<T, N> 与原生数组 T[N] 具有相同的内存大小,并且默认都是分配在栈内存
  • std::array 相比原生数组多了更多的可操作性和属性, 比如获取数组大小可以直接使用 array.size(), 整数数组清零可以使用 array.fill(0)
  • std::array也支持原生数组相同的 for each循环
  • 总之就是,原生数组能做的事,std::array都可以做,std::array可以做的事,原生数组不一定可以做
  • 建议优先使用 std::array

使用方法

包含头文件

#include <array>

定义与初始化

  • 局部变量
// 使用传统默认构造: 每个元素都会调用默认构造
std::array<int, 100> numbers; // C++11前的语法
std::array<int, 100> numbers{}; // C++11后的语法

// 使用 auto
auto numbers = std::array<int, 10>{}; // C++11开始支持

  • 类成员变量
class Dog {
public:
	class Leg { /* 内容忽略 */};
private:
	std::array<Leg, 4> legs_ {};
};

使用场景

建议使用的场景

数量固定的相同元素作为一个整体时

不建议使用的场景

一次分配超大空间,使用局部内存加辅助长度信息存储长度不固定的元素。这种场景,应该使用支持动态扩容的 std::vector

字节数组妙用

字节数组

表示数组的元素大小只有一个字节, 比如 std::array<char, 8>, std::array<uint8_t, 256>, std::array<std::byte, 1024>等等

有何妙用?

可以比较方便的操作内存块的任意字节

虽然 std::array 默认定义时,使用的时栈内存,但不妨碍我们使用堆内存或者其他内存,所以std::array所使用的内存属于什么类型,完全取决于我们的初始化方式.。比如:

  • 函数内定义的局部普通实例, 使用的是栈内存
int func()
{
	std::array<uint8_t, 32> batch; // 占内存,建议不要分配过大导致栈溢出
	return 0;
}
  • 静态变量, 包括函数内静态变量, 全局变量, 类静态变量 , 使用的是静态内存,地址和大小都是固定的
  • new, malloc, 智能指针等创建的实例,使用的都是堆内存实例 + 一个栈内存指针
  • 直接定义指针,可以指向任意内存块
static std::array<char, 1024> large_buffer;

void func()
{
	std::array<char, 16> small_buffer;
	
	auto p1 = new std::array<char, 8>{}; // 指向分配的堆内存
	auto p2 = &large_buffer; // 指向静态内存
	auto p3 = &small_buffer; // 指向栈内存
}
  • 甚至可以指向一个带有实际类型的内存块,可以你方便的操作该内存块的任意字节
struct Info { /* 内容忽略 */};

void func()
{
	Info info;
	
	
	auto p = reinterpret_cast<std::array<char, sizeof(Info)> *>(&info); // 此时的p所指向的内存块与 `info`变量完全一致, 可以操作p的任意字节,修改的就是info对应的内存

	std::cout << p->size() << std::endl; // 显示info结构体的大小

	(*p)[0] = 0xff;  // 将info结构体的第一个字节改为 0xff

	std::cout << (*p)[3] << std::endl; // 显示info结构体的第四个字节

	// 如果能确保生命周期的安全性,甚至可以直接定义为引用
	auto& ref = *reinterpret_cast<std::array<char, sizeof(Info)> *>(&info);

	ref[0] = 0; // 对info结构体的第一个字节清0
	
	ref.fill(0); // 对整个info结构体清零

	for (auto byte: ref) {
		// 遍历info结构体的每一个字节
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值