指针与数组的对比
传送门:http://blog.csdn.net/csdn_lsd/article/details/78553918
- C/C++程序中,指针和数组在不少地方可以互相替换着用,让人产生错觉,以为两者是等价的。
- 数组要么在静态存储区被创建(全局数组),要么在栈上被创建(函数体内数组),数组名对应一块内存而不是指向,其地址和空间大小在生命周期内保持不变,只有数组的内容可以改变。
- 指针(非常量指针)可以随时指向任意类型的内存块,它的特性是可变,所以我们常用指针来操作动态内存。
修改内容
- char a[]=”hello”;a[0] = x;//可以
- char a[] = {‘h’,’e’,’l’,’l’,’o’};//没有’\0’
- char *p = “hello”;p[0] = x;//编译通过,运行崩溃
内容复制与比较
- 不能对数组名进行直接复制与比较,若想把数组a的内容复制给数组b,不能用语句b=a;应该用标准库函数strcpy进行复制。
- 不能用b==a比较内容是否相等,应该用strcmp。
- 语句p=a并不能把a的内容复制给指针p,而是把a的地址赋给了p。要想复制a的内容,可以先用库函数malloc为p申请一块容量为strlen(a)+1个字节的内存,再用strcpy进行字符串复制。
char a[] = "hello world";
int len = strlen(a);//不包括'\0'
char *p = (char *)malloc(sizeof(char)(len+1));//为'\0'预留一个位置
strcpy(p,a);
计算内存容量
- 运算符sizeof可以计算出数组的容量(字节数)。
参数传递
- 当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针,意思是:在被掉函数中,接收的是一个地址,并没有发生值拷贝,而且原来的数组还是原来的数组。
//错误代码例子
void getmemory(char *p, int num) //这个p是临时的替身
{
//p = str = null;
p = (char *)malloc(sizeof(char) * num); //null = malloc
}
void test(void)
{
char *str = null; //str为真身
getmemory(str, 100); // str 仍然为 null
strcpy(str, "hello"); // 运行错误
}
//正确代码例子
void getmemory2(char **p, int num) //送来一个地址
{
*p = (char *)malloc(sizeof(char) * num); //往地址里放货
}
void test2(void)
{
char *str = null;
getmemory2(&str, 100); // 注意参数是 &str,而不是str
strcpy(str, "hello");
cout<< str << endl;
free(str);
}
有了malloc/free为什么还要new/delete
- malloc与free是c/c++语句的标准库函数,new/delete是c++的运算符。
- 对于非内部数据结构(类的对象),用malloc无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此c++需要一个能完成动态内存分配和初始化工作的运算符new,和一个能完成清理和释放内存的运算符delete。
- new: new内置了sizeof、类型转换和类型安全检查功能。new在创建动态对象的同时完成了初始化工作。如果对象有多个构造函数,那么new的语句也有多种形式。
class obj
{
public :
obj(void); // 无参数的构造函数
obj(int x); // 带一个参数的构造函数
…
}
void test(void)
{
obj *a = new obj;
obj *b = new obj(1); // 初值为1
…
delete a;
delete b;
}
//如果用new创建对象数组,那么只能使用对象的无参构造函数
obj *objects = new obj[100];//创建100个动态对象
//不能写成
obj *objects = new obj[100](i);//创建100个动态对象的同时赋值1
- delete:在用delete释放对象数组时
delete []objects; // 正确的用法
delete objects; // 错误的用法
后者相当于delete objects[0],漏掉了另外99个对象。
内存耗尽怎么办
- 对于32位以上的应用程序而言,无论怎样使用malloc与new,几乎不可能导致“内存耗尽”。我在windows 98下用visual c++编写了测试程序,见示例7。这个程序会无休止地运行下去,根本不会终止。因为32位操作系统支持“虚存”,内存用完了,自动用硬盘空间顶替。我只听到硬盘嘎吱嘎吱地响,window 98已经累得对键盘、鼠标毫无反应。
参考:http://developer.51cto.com/art/201107/272734.htm