《数据结构算法与应用》编写一个函数changeLength2D,用以改变一个二维数组的长度。二维数组的每一维的长度都是可以变化的

来源:互联网 发布:巴黎世家机车包 知乎 编辑:程序博客网 时间:2024/06/03 21:03
这是第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;}

阅读全文
0 0