一、对于普通数组来说,在定义或初始化时必须确定元素个数,即下标必须是已知的,即在编译时已知。
例:定义数组时 int a[6];
初始化数组时,float a[]={12.3,89.6,-12.56,3.9};
对数组a来说,虽然没有下标,但是通过{}中的元素个数,可以查出其下标为4。
像这样的格式:
int a[]; 错误,下标未知
int a[n]; 错误,同上
int m=10; int a[m]; 错误,m是变量,在编译时未知
对于下面格式:
const int size=50;
const int chs=size*sizeof(int);
int a[size];
char s[chs];
由于size和s是常量,它们在编译时可知,所以格式正确。
所以常量可以作为下标。
二、通过堆内存分配,可以在定义或初始化时不必确定确定元素个数,即在编译时不知,而在运行时已知。
1、使用malloc和free
其语法要求:
(1) #include<alloc.h>
(2) 指针名=void* malloc (内存大小);
(3) free(指针名);
说明:
(1)其中的void*为默认类型,表明这个内存空间类型不确定。如果要确定其类型,则必须进行强制类型转换。
(2)内存的大小可以直接写出,也可以通过元素个数乘以sizeof(type)计算。
例1:
#include < alloc.h >
void main()
{
int arraysize;
int * array;
cout << " 请输入数组个数 " << endl;
cin << arraysize;
array = ( int * )malloc(arraysize * sizeof ( int ));
……
free(array);
}
其中(int*)进行强制类型转换,(arraysize *sizeof(int))计算array堆内存所占的空间量。
free(array)用来释放堆内存。
2、使用new和delete
其语法要求:
动态变量 | 动态数组 |
不需要文件头 | 不需要文件头 |
指针名=new 类型名; | 指针名 = new 类型名[元素个数]; |
delete 指针名; | delete [ ]指针名; |
说明:
(1)不需要头文件
(2)动态数组只需要元素个数,不需要计算其内存空间
(3)malloc定义空间时用(),而new定义空间时用[ ]
(4)对动态变量可以直接初始化,格式为 指针名=new 类型名(初始化值)
例2:
void main()
{
int arraysize;
int * array;
cout << " 请输入数组个数 " << endl;
cin << arraysize;
array = new int [arraysize];
……
delete [ ]array;
}
三、分配内存失败
在分配动态内存时,有时候因为内存被占用,可以会分配失败,在这样的情况下,后面的操作是无效的。所以要设定一个判定条件,让内存分配成功时再运行。
内存分配失败的标志是,动态指针的值为NULL,所以可以用if判定。
因此上述两个例子可以改为:
例1改为:
#include < alloc.h >
void main()
{
int arraysize;
int * array;
cout << " 请输入数组个数 " << endl;
cin << arraysize;
if ((array = ( int * )malloc(arraysize * sizeof ( int ))) = NULL)
return ;
else ……
free(array);
}
例2改为:
void main()
{
int arraysize;
int * array;
cout << " 请输入数组个数 " << endl;
cin << arraysize;
if ((array = new int [arraysize]) = NULL)
return ;
else ……
delete [ ]array;
}
四、malloc和free是C语言的命令,new和delete是C++的命令,推荐使用后者,因功能更强大。
动态分配内存后,必须手工删除。否则会导致内存溢出。