一、内存分配有三种方式:
(1)从静态存储区域分配。内存在程序编译时就已分好,在程序的整个运行期间都存在。例如全局变量,static变量,常量字符串。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配,亦称动态内存分配。程序运行时用malloc或new申请任意多少的内存,用free或delete释放。
规则:
(1)申请内存以后,检查指针是否是NULL,避免内存申请不成功。
(2)给内存赋初值。
(3)避免数组或指针的下标越界。
(4)动态内存的申请与释放必须配对。
(5)释放内存以后,将指针赋为NULL,避免野指针。
二、数组与指针的比较:
(1)数组要么在静态存储区创建(全局数组),要么在栈上创建。数组名对应着(不是指向)一块内存区域,其地址和容量在生存期内不变。
(2)指针可以随时指向任意类型的内存块,它的特征是可变。
例:
char a[] = "hello";(相当于用一个常量字符串初始化一个char数组,常量字符串存在静态存储区)
a[0]= 'X';
cout<<a<<endl;
结果:√,Xello
char *p = "world";
p[0] = 'X';
cout<<p<<endl;
结果:×,运行错误。
原因:p指向常量字符串,常量字符串的内容是不可以被修改的。
三、sizeof计算内存容量:
char a[10];sizeof(a) = 10;
char *p;sizeof(p)=4;
注意当数组作为函数的参数传递时,该数组自动退化为同类型的指针。
void Fun(char a[100])
{
sizeof(a) = 4;
}
四、malloc/free和new/delete
malloc/free是库函数,不能自动执行类的构造和析构函数。
new/delete是运算符,能自动执行构造和析构函数,完成初始化和清理工作。
内部数据类型没有构造和析构的过程,所以用malloc/free和new/delete都一样。
五、内存耗尽
如果申请动态内存时,找不到足够大的内存块,malloc/new将返回NULL指针。
如果指针p是NULL,free(p)多少次都没有问题。
如果指针p不是NULL,free(p)两次就会运行错误。
用delete释放数组时,不要丢'[]'。
delete []p;
delete p;只释放了p[0]