动态分配数组空间

1.变长一维数组

这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组。实现变长数组最简单的是变长一维数组,你可以这样做:

[cpp] view plaincopy

  1. //文件名:   array01.cpp
  2. #include <iostream>
  3. using   namespace   std;
  4. int   main()
  5. {
  6. int   len;
  7. cin> > len;
  8. //用指针p指向new动态分配的长度为len*sizeof(int)的内存空间
  9. int   *p=new   int[len];
  10. ...........
  11. delete[]   p;
  12. return   0;
  13. }

注意int   *p=new   int[len];这一句,你不能这样做: int   p[len];

C++编译器会报错说len的大小不能确定,因为用这种形式声明数组,数组的大小需要在编译时确定。而且这样也不行:

int   p[]=new   int[len];

编译器会说不能把int*型转化为int[]型,因为用new开辟了一段内存空间后会返回这段内存的首地址,所以要把这个地址赋给一个指针,所以要用int   *p=new   int[len];

array01.cpp实现了一个变长的一维数组,但是要养成一个好习惯,就是注意要注销指针p,使程序释放用new开辟的内存空间。

当然使用C++标准模版库(STL)中的vector(向量)也可以实现变长数组:

[cpp] view plaincopy

  1. //文件名:   array02.cpp
  2. #include <iostream>
  3. #include <vector>
  4. using   namespace   std;
  5. int   main()
  6. {
  7. int   len;
  8. cin> > len;
  9. vector <int>   array(len);//声明变长数组
  10. for(int   i=0;i <len;i++)
  11. {
  12. array[i]=i;
  13. cout < <array[i] < < "/t ";
  14. }
  15. return   0;
  16. }

这里的变长数组让我联想到了java的java.util包中的vector和C#中的ArrayList,它们也可以在各自的语言中实现变长数组。不过C++中的vector不能像C#一样有托管的垃圾回收机制回收被占用的内存空间,但是你可以在使用完vector后调用~vector()析构函数释放内存。

2.变长n维数组

变长的n维数组实现起来有些麻烦,但是在工程与软件设计应用中常使用的是二维数组,所以在这里着重介绍变长的二维数组,变长的n维数组可以按照类似的方法实现。首先看一个经典的用C实现变长二维数组的例子:

[cpp] view plaincopy

  1. //文件名:   array03.c
  2. #include     <stdio.h>
  3. #include     <malloc.h>
  4. void     main()
  5. {
  6. int     x,y,i,j;
  7. float     **a,*b;
  8. printf( "请输入你所求解的线性方程组的行数x:x= ");
  9. scanf( "%d ",&x);
  10. printf( "请输入你所求解的线性方程组的列数y:y= ");
  11. scanf( "%d ",&y);
  12. a=(float  **)malloc(sizeof(float  *) *x);
  13. b=(float  *)malloc(sizeof(float)  *x);
  14. for(i=0;i <x;i++)
  15. {
  16. *(a+i)=(float  *)malloc(sizeof(float)  *y);
  17. }
  18. /*读入数据*/
  19. printf( "请按行的顺序依次输入系数的值(共%d项): ",x*y);
  20. for(i=0;i <=x-1;i++)
  21. for(j=0;j <=y-1;j++)
  22. scanf( "%f ",&a[i][j]);
  23. printf( "请按列的顺序依次输入常数的值(共%d项): ",x);
  24. for(j=0;j <=x-1;j++)
  25. scanf( "%f ",&b[j]);
  26. printf( "您输入方程组的增广矩阵为:/n ");
  27. for(i=0;i <=x-1;i++)
  28. {
  29. for(j=0;j <=y-1;j++)
  30. printf( "%.5f",a[i][j]);
  31. printf( "%.5f",b[i]);
  32. printf( "/n ");
  33. }
  34. free(b);
  35. for(i=0;i <x;i++)
  36. free    (*(a+i));
  37. }

那么用C++怎样实现呢?在C++中可以通过new和delete运算符动态开辟和释放空间,其中new与C中malloc函数的功能相似,delete与C中free函数的功能相似。用C++实现变长二维数组时可以采用两种方法:双指针方法和使用STL中vector(向量)的方法。

首先介绍一下双指针方法,在这里双指针就是指像指针的指针,比如你可以这样声明一个数组:

int   **p   =   new   int*[num1];

而对每一个*p(一共num1个*p)申请一组内存空间:

for(int   i=0;   i <num1;   ++i)

p[i]   =   new   int[num2];

其中,num1是行数,num2是数组的列数。测试的源程序如下:

[c-sharp] view plaincopy

  1. //文件名:   array04.cpp
  2. #include   <iostream>
  3. #include   <iomanip>
  4. using   namespace   std;
  5. int   main()
  6. {
  7. int   num1,//行数
  8. num2;//列数
  9. cout < < "Please   enter   the   number   for   row   and   column:   " < <endl;
  10. cin   > >   num1   > >   num2;
  11. //为二维数组开辟空间
  12. int   **p   =   new   int*[num1];
  13. for(int   i=0;   i <num1;   ++i)
  14. p[i]   =   new   int[num2];
  15. for(int   j=0;j <num1;j++)
  16. {
  17. for(int   k=0;k <num2;k++)
  18. {
  19. p[j][k]=(j+1)*(k+1);
  20. cout < <setw(6) < <p[j][k] < < ‘: ‘ < <setw(8) < <&p[j][k];
  21. }
  22. cout < <endl;
  23. }
  24. //释放二维数组占用的空间
  25. for(int   m=0;m <num1;m++)
  26. delete[]   p[m];
  27. delete[]   p;
  28. return   0;
  29. }

以下是运行结果:

Please   enter   the   number   for   row   and   column:

4   5

1:004915F0           2:004915F4           3:004915F8           4:004915FC           5:00491600

2:00491180           4:00491184           6:00491188           8:0049118C         10:00491190

3:00491140           6:00491144           9:00491148         12:0049114C         15:00491150

4:00491100           8:00491104         12:00491108         16:0049110C         20:00491110

Press   any   key   to   continue

程序清单array04.cpp可以显示分配的内存空间单元的地址,大家可以看到,由于数组空间是动态分配的,数组行之间的地址空间是不连续的,因为不同行的数组元素的地址空间是用不同的new来分配的。而每一行之中列之间的地址空间是连续的。

那么用vector(向量)怎样实现二维数组呢?以下给出源程序:

[cpp] view plaincopy

  1. //文件名:   array05.cpp
  2. #include   <iostream>
  3. #include   <vector>
  4. #include   <iomanip>
  5. using   namespace   std;
  6. int   main()
  7. {
  8. int   i,
  9. j,
  10. m,   //行数
  11. n;   //列数
  12. cout   < <   "input   value   for   m,n: ";
  13. cin> > m> > n;
  14. //注意下面这一行:vector <int后两个 "> "之间要有空格!否则会被认为是重载 "> > "。
  15. vector <vector <int>   >   vecInt(m,   vector <int> (n));
  16. for   (i   =   0;   i   <   m;   i++)
  17. for   (j   =   0;   j   <   n;   j++)
  18. vecInt[i][j]   =   i*j;
  19. for   (i   =   0;   i   <   m;   i++)
  20. {
  21. for   (j   =   0;   j   <   n;   j++)
  22. cout < <setw(5) < <vecInt[i][j] < < ": " < <setw(9) < <&vecInt[i][j];
  23. cout < <endl;
  24. }
  25. return   0;
  26. }

以下是运行结果:

input   value   for   m,n:3   4

0:   00491180         0:   00491184         0:   00491188         0:   0049118C

0:   00491140         1:   00491144         2:   00491148         3:   0049114C

0:   00491100         2:   00491104         4:   00491108         6:   0049110C

Press   any   key   to   continue

大家可以看到,这里vector中元素的内存的地址分配也有同双指针实现的二维数组有同样的特点。不过用vector的方法比使用双指针简单地多,分配内存空间时会更安全,数组初始化代码也更简单,所以本人建议使用STL中的vector来实现变长多维数组。以下是一个变长三维数组:

[cpp] view plaincopy

  1. //文件名:   array06.cpp
  2. #include   <iostream>
  3. #include   <vector>
  4. #include   <iomanip>
  5. using   namespace   std;
  6. int   main()
  7. {
  8. int   i,
  9. j,
  10. k,
  11. m,   //一维坐标
  12. n,   //二维坐标
  13. l;   //三维坐标
  14. cout   < <   "input   value   for   m,n,l: ";
  15. cin> > m> > n> > l;
  16. vector <vector <vector <int>   >   >   vecInt(m,   vector <vector <int>   > (n,   vector <int> (l)));
  17. for   (i   =   0;   i   <   m;   i++)
  18. for   (j   =   0;   j   <   n;   j++)
  19. for(k   =   0;   k   <   l;   k++)
  20. vecInt[i][j][k]   =   i+j+k;
  21. for   (i   =   0;   i   <   m;   i++)
  22. {
  23. for   (j   =   0;   j   <   n;   j++)
  24. {
  25. for(k   =   0;   k <l;   k++)
  26. cout < <setw(5) < <vecInt[i][j][k] < < ": " < <setw(9) < <&vecInt[i][j][k];
  27. cout < <endl;
  28. }
  29. cout < <endl;
  30. }
  31. return   0;
  32. }

运行结果:

input   value   for   m,n,l:2   3   4

0:   00492FE0         1:   00492FE4         2:   00492FE8         3:   00492FEC

1:   00492FA0         2:   00492FA4         3:   00492FA8         4:   00492FAC

2:   00492F60         3:   00492F64         4:   00492F68         5:   00492F6C

1:   00492EC0         2:   00492EC4         3:   00492EC8         4:   00492ECC

2:   00492E80         3:   00492E84         4:   00492E88         5:   00492E8C

3:   00492E40         4:   00492E44         5:   00492E48         6:   00492E4C

动态分配数组空间

时间: 2024-10-15 12:04:02

动态分配数组空间的相关文章

new?动态分配数组空间?.xml

pre{ line-height:1; color:#3c3c3c; background-color:#d2c39b; font-size:16px;}.sysFunc{color:#627cf6;font-style:italic;font-weight:bold;} .selfFuc{color:#800080;} .bool{color:#d2576f;} .condition{color:#000080;font-weight:bold;} .key{color:#000080;} .

C语言动态数组空间分配问题

**动态数组起源:** 在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定.对于这种问题,用静态数组的办法很难解决.为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数结合指针可以按需要动态地分配内存空间,来构建动态数组,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段.动态数组的内存空间是从堆(heap)上分配(即动态分配)的.是通过执行代码而为其分配存储空间.当程序执行到这些语句时,才为其分配.程序员自己负责释放内存.对内存的动态

C语言数组空间的初始化详解

数组空间的初始化就是为每一个标签地址赋值.按照标签逐一处理.如果我们需要为每一个内存赋值,假如有一个int a[100];我们就需要用下标为100个int类型的空间赋值.这样的工作量是非常大的,我们就想到了让编译器做一些初始化操作,初始化操作是第一次赋值,第二次赋值就不能再这样赋值了. int a[10]=空间: 我需要给它一个空间,让它对这里面的值进行批量处理:比如int a[10]={10,20,30}; //a[1]=10,a[2]=20,a[3]=30,a[4]=-=a[9]=0所以实际

C++之动态分配数组内存空间

动态分配也需要一个值来确定数组的长度,指不定过这个值可以是动态的值,而不是常量. 1.malloc int *p=(int*)malloc(n*sizeof(int)); 其中n是动态数值,表示数组的大小. 2.vector 动态分配一维数组: int n=3; vector<int> a(n); 动态分配二维数组: int n=3; vector<vector<int>>a(n,vector<int>(3)); 原文地址:https://www.cnblo

C++中使用new动态生成一个数组空间以及使用delete对存储空间进行释放

1 // 使用new动态分配存储空间 2 3 #include<iostream> 4 using std::cout; 5 6 int main() 7 { 8 // 第1种方式 9 int *a=new int; 10 *a=1; 11 cout<<"使用第一种方式进行动态分配存储空间的结果为:\n" 12 <<"*a= "<<*a<<std::endl; 13 delete a; // 释放动态存储空

初始化动态分配数组

圆括号将动态分配的int型数组  初始化为 0:

数据结构应用案例——栈结构用于8皇后问题的回溯求解

[说明]本文来自由周世平老师主编的<C语言程序设计>教材.我作为参编人员执笔了第7.8章."第8章 问题求解与算法"中"8.6.1 回溯法"以8皇后问题的求解为例,介绍了回溯法的解题过程.这个解决方案中用到了"栈",引用至此,作为栈应用的例子.需要说明的是,教材面向程序设计初学者,并全文中并未提出过任何关于"栈"的描述.这样做,隐藏了术语,减少初学者的认知难度.对于数据结构的学习者而言,由于知识面的扩大,却用不着回

指针杂谈 &amp;&amp; memory leak

1.声明一个指针 int *pcount: //一个指向int variable的指针,命名为pcount int count = 5: pcount = &count://&是取地址符, *pcount=&count是错的 cout << count; //5 cout << pcount; //输出count存储的内存地址 cout << &count; //输出count存储的内存地址 cout << *pcount;

基于动态分配的数组的顺序表(兼具Boost单元测试)

我们利用静态分配的数组来实现的顺序表的局限还是挺大的,主要在于它的容量是预先定好的,用户不能根据自己的需要来改变.如果为了后续用户能够自己调整顺序表的大小,动态地分配数组空间还是很有必要的.基于动态分配的数组的顺序表绝大部分跟基于静态分配的数组的顺序表是一样的,只需在后者程序上改动一小部分即可. 第一,我们不需定义一个容量常量CAPACITY,而是定义一个私有变量myCapacity. 第二,类的构造函数需要改进一下.我们需要类在被实例化时自动申请内存,即需添加下边程序: ElementType