由【C++简单实现java的Arraylist部分功能】学到的

严格来讲不应该使用这个标题,因为我写这个代码只是练习了一下模板,这里并没有实现多少arraylist的东西,而且其中的原理也很不严谨。不过在这个代码中也学到了一些东西,在这里简单提及总结一下。

我的java_Arraylist类定义在一个hpp文件。首先是它的变量,一个T指针,用来指向数组,另外两个int,一个用来管理length,一个用来管理size。

这里之所以要使用指针,是方便后面数组扩容,可以方便的用指针指向扩容后的另一个数组。

template<typename T>
class java_Arraylist {

private:
	T *arr;
	int arr_len = 0;
	int arr_size = 0;

然后是两个构造方法,指针指向一个初始化长度为10的数组,这里没什么好说的。

public:

	java_Arraylist() {
		arr = new T[10];
		this->arr_len = 0;
		this->arr_size = 10;
	}
	java_Arraylist(int length) {
		arr = new T[length];
		this->arr = arr[length];
		this->arr_len = 0;
		this->arr_size = length;
	}

接着是get和size方法,在java中它们分别负责获取指定下标和获取length,此处没有做太多情况考虑,所以写得也很简单。

	T get(int index) {
		return this->arr[index];
	}

	int size() {
		return arr_len;
	}

最后是add方法,向list的最后一位插入数据。这里要考虑到数组容量的问题,进行扩容。

在将arr的值给到temp_arr后,arr指向的内存空间便可以释放了。随后将arr重新指向temp_arr指向的空间,所以此时不能delete[] temp_arr。只需要将它指向nullptr,将空间交由arr指针管理。

void add(T t) {
	if (arr_len < arr_size) {
		this->arr[arr_len] = t;
		arr_len++;
	}
	else {
		T* temp_arr = new T[arr_size * 2];
		for (int i = 0; i < arr_len; i++) {
			temp_arr[i] = arr[i];
		}
		delete[] arr;
		arr = temp_arr;
		temp_arr = nullptr;
		arr[arr_len] = t;
		arr_size = arr_size * 2;
		arr_len++;
	}
}

我在第一次写的时候,因粗心大意,在扩容部分T* temp_arr = new T[arr_size * 2]处,忘了*2,这样一来,新生成的数组和原来的容量一样大。然而通过main方法测试时,惊奇的发现,在add数据超过下标后,还可以继续add数据,甚至可以通过get打印出来。

这就很奇怪了,但是无论通过sizeof还是debug,都无法获取到new出来的数组的容量,难道说int* a = new int[10],它的容量不是10?

难道说我设置并维护的size变量,是自己跟自己过家家,没有起到应有的作用?

经过一番查询,我查到了这样一个资料:_msize()函数,可以通过指针获取到指针指向的空间内存大小,由于我创建的是int型,所以此处数组每个元素所占内存大小为4,根据_msize()得到40,果然对上了,但是为什么超过下标10还能继续读呢?

又测试了一番,得到一个关键字:缓冲区溢出。按照我的程序,编译器并不知道这里可能会越界,在此处甚至不会有任何提示,但如果直接在main函数中创建数组,并且在越界下标处插入数据,就会检测到下标越界,发出提示“缓冲区溢出”,但此时程序依然可以运行。

原来C++并不会检查数组的下标,指针只获得了数组的地址,没有获得数组的长度,所以程序可以运行成功。但这并不代表就可以这样做,因为数组越界,使用了不属于数组的未知的内存,如果这段内存中还有其他的数据,就可能造成不可预知的结果,程序员必须管理好数组的下标。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值