《数据结构算法与应用》编写一个函数changeLength2D,用以改变一个二维数组的长度。二维数组的每一维的长度都是可以变化的
这是第5章的一道习题,在编写过程中花掉了一些时间,在这里将自己所整理的知识梳理一下。思路:首先,要改变一个2维数组的行和列的长度,就要获得行和列的地址,把新的行和列的长度和原先的行列长度在模板函数中进行处理,并且要有原先数组的地址,因此,自定义模板函数需要有5个入口参数。其次,数组的大小不知道,所以赋值的时候可能会出现开辟的内存不够,或者新数组的长度太大等问题,这里,可以采用书上的思路,用algorithm中的min函数,才进行赋值操作。第三,采用指针指向二维数组,在模板函数中进行动态开辟新数组,要获取每一维数组的首地址,就一定会用到for循环进行寻址赋值,在开辟新数组并进行赋值打印(打印是为了证明自己的函数是不是正确了,方便测试)后,要对原先数组的内存进行释放。
实现一维数组的开辟和释放,你可以这么做:
int n; cin>>n>>endl; int* arr=new int[n];
释放时,只需要这样:
delete[] arr;
这里要注意的是[]不能少,不然,delete不能完全释放数组所占的内存空间。对于二维数组,我们可以这样:
int num1,num2;
cin>>num1>>num2>>endl;
int **arr=new int*[num1];
for(int i=0;i<num1;i++)
arr[i]=new int[num2];
释放时不能简单的像一维那样:
delete[] arr;
而要这样:
for(int i=0;i<num1;i++) delete[] arr[i]; delete[] arr;
下面进行测试,发现C++编译出错,写入内存错误,最后发现是这个地方出现了问题:静态分配的内存在栈里,每进入一个函数时都会建栈,栈里会存放函数用到的参数、局部变量等信息,函数执行完以后,会出栈销毁栈,这个过程就会释放你静态分配的数组内存,这是由系统自动完成的。动态分配的内存,实际在堆上,系统没法自动帮你去释放堆上的内存,需要你自己写free或者delete来告诉操作系统需要帮你去释放堆上哪个位置的内存。因此,在测试的时候的实际数组不能是静态数组,而应该是动态数组。改完以后就发现错误没有啦。
测试代码如下:
#include <iostream> #include <algorithm> using namespace std; template<class T> void changeLength2D(T** a, int oldNum1,int oldNum2, int newNum1,int newNum2) { /*if (newNum1 < 0 || newNum2<0) throw illegalParameterValue("new length must be >= 0");*/ T** temp = new T*[newNum1]; // new array for(int i=0;i<newNum1;i++) { temp[i]=new T[newNum2]; } int num1 = min(oldNum1, newNum1); // number to copy int num2=min(oldNum2,newNum2); for(int i=0;i<num1;i++) { copy(a[i],a[i]+num2,temp[i]); } for(int i=0;i<oldNum1;i++) { delete [] a[i];// deallocate old memory } delete[]a; a = temp; for (int i=0;i<num1;i++) for(int j=0;j<num2;j++) cout<<temp[i][j]<<endl; } int main() { int m=3,n=2; int**a=new int*[m]; for(int i=0;i<m;i++) { a[i]=new int[n]; } for(int i=0;i<m;i++) for(int j=0;j<n;j++) a[i][j]=j; changeLength2D(a,3,2,4,2); system("pause"); return 0; }
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: IOS之NSArray 中调用的方法详解(1)
- 下一篇: iOS中数组遍历的方法及比较