指针与数组的对比
传送门: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);
char *p = (char *)malloc(sizeof(char)(len+1));
strcpy(p,a);
计算内存容量
- 运算符sizeof可以计算出数组的容量(字节数)。
参数传递
- 当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针,意思是:在被掉函数中,接收的是一个地址,并没有发生值拷贝,而且原来的数组还是原来的数组。
void getmemory(char *p, int num)
{
p = (char *)malloc(sizeof(char) * num);
}
void test(void)
{
char *str = null;
getmemory(str, 100);
strcpy(str, "hello");
}
void getmemory2(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
void test2(void)
{
char *str = null;
getmemory2(&str, 100);
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);
…
delete a;
delete b;
}
obj *objects = new obj[100];
obj *objects = new obj[100](i);
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