C++学习笔记 06 数组

一、数组的创建

  1. 栈分配:int example[5]; 方法结束栈空间自动释放
  2. 堆分配:int* arr = new int[5]; 需要手动删除
#include<iostream>

int main() {
	//1. 栈上分配数组空间,当前方法结束自动释放空间(栈空间内存有限),不必手动删除
	int example[5];

	//2. 堆上分配内存空间,可以通过return返回
	int* arr = new int[5];

	//堆数组必须手动delete
	delete[] arr;

	std::cin.get();
}

内存间接寻址(Memory Indirection)

一个指针,指向另一个指针
p1 --> p2 --> Arr

这会产生内存碎片和缓存丢失

栈空间分配数据直接寻址

堆数组在内存中对象区间存一个地址,需要跳转

对象数组属性在堆中数组数据

在类对象地址上再去找到另一个堆中地址(本对象中属性在堆中的地址),这意味着我们基本要在代码里跳来跳去,所以,如果可以,你应该在栈上创建数组来避免这种情况,因为这样的内存跳跃肯定会影响性能。

二、计算数组大小的注意事项

1. C++ 11 std::array

内置数据结构,定义在C++11 标准库中。很多人喜欢用它来替代原生数组,因为有很多优点,有边界检查,记录数组大小。我们没有办法计算原生数组大小。

2. 原生计算

sizeof(变量名) / sizeof(类型)不可信。只对栈分配有效,对堆指针分配方式无效

#include<iostream>
#include<array>

//个人而言,总是用原生数组,大多数人都这么用,会更快一些。但如果你想安全,你可能想用std::array,
//std::array比原生数组安全得多,但我就喜欢危险
class Entity {
public:

	//1. 必须是 static + const, 否则报错
	static const int stackArrSize = 5;
	int arr[stackArrSize];

	//2. 也可以用constexpr
	static constexpr int stackArrSize2 = 5;
	int arr2[stackArrSize2];

	//3. 堆数组指针以非常量分配大小不存在编译问题
	int s1 = 5;
	int* arrP = new int[s1];

	//4. array
	std::array<int, 5> arrayInstance;
	

	//1. 栈上分配:栈上地址 + 偏移量。
	int arrStack[5];
	//2. 堆上分配,
	int* arrHeep = new int[5];

	Entity() {
		//int 4个字节 * 5个元素 =20个字节 / int 4个字节
		int count = sizeof(arrStack) / sizeof(int); // 5
		//int指针大小 8个字节(64位) / int 4个字节
		int count2 = sizeof(arrHeep) / sizeof(int); // 2
		std::cout << count << " vs " << count2 << std::endl; //5 vs 2

		//计算数组大小,用array当然比原生自定义数组会有额外开销,做边界检查,它也维护了一个整数类型size,实际你可能不需要size。
		//通常这些额外开销是值得的。
		std::cout << arrayInstance.size() << std::endl;
	}
};

int main() {
	Entity e;

	//1. 栈上分配数组空间,当前方法结束自动释放空间(栈空间内存有限),不必手动删除
	int example[5];

	//2. 堆上分配内存空间,可以通过return返回
	int* arr = new int[5];

	//堆数组必须手动delete
	delete[] arr;

	std::cin.get();
}

总结:你要自己维护数组大小。这确实很麻烦,但是C++就是这样工作的,你必须去维护它。

栈中分配数组注意事项

当你在栈中为数组申请内存时,它必须是一个编译时就知道的常量,所以必须用static标记。这里还可以用constexpr表达式。类中常量表达式必须是静态的。

常量分配数组size的错误❌️

posted @ 2025-12-11 09:54  超轶绝尘  阅读(8)  评论(0)    收藏  举报