一、地址
1.对于32位的操作系统,地址都是32位的,前0不可以省略
例:
- int *p = NULL;
- cout<<p<<endl;//输出00000000,而不是0
int *p = NULL;
cout<<p<<endl;//输出00000000,而不是0
2.指针可以通过内存地址直接访问数据,可避免在程序中复制大量的代码。因此指针效率最高
例:a[j]:a+j
a[i][j]:a[i]+j
二、内存
1.数据在内存中的存放形式
1)栈区:由编译器自动分配和释放
一般存放函数的参数值、局部变量的值等
2)堆区:由程序员分配及释放。若程序员不释放,程序结束后可能由OS回收
3)寄存器区:用来保存栈顶指针和指令指针
4)全局区(静态区):全局变量和静态变量是存储在一起的。初始化的和未初始化的是分开的。
程序结束后由系统释放
5)文字常量区:程序结束后由系统释放
存放常量字符串
6)程序代码区:存放函数体的二进制代码
2.堆与栈的区别:
堆 | 栈 | |
---|---|---|
内存申请方式 | 程序员自己申请,申请时需要指明申请的大小 | 系统自己分配 |
系统响应方式 | 遍历内存空闲地址链表,找到比申请的要大的堆结点,将其 中申请的大小分配给程序,程序空间放入空闲链表中 | 栈的剩余空间不足时会overflow |
最大空间大小 | 由系统中的有效虚拟内存决定 | 2M |
执行效率 | 慢、易产生内存碎片、灵活 | 快、无内存碎片 |
补充:
(1)指针对内存数据有保护作用
栈可以为它其中的某个内存单元命名,但堆中的每个内存单元都是匿名(这是对数据的保护)的。必须先在堆中申请一个内存单元地址,然后把它的保存在一个指针中,只有该指针才可以访问该内存单元的数据。
(2)delete运算符只能删除堆中的空间,删除栈中的空间会导致出错
- int main()
- {
- A a;
- A *p = new A;
- A *q = &a;
- delete p;//正确,因为p指向堆中的未命名空间
- delete q;//错误,因为q指向栈中的空间
- return 0;
- }
int main()
{
A a;
A *p = new A;
A *q = &a;
delete p;//正确,因为p指向堆中的未命名空间
delete q;//错误,因为q指向栈中的空间
return 0;
}
3.内存泄漏
(1)某指针指向某堆结点,没有释放
(2)指针是一个局部变量,在释放内存之前,因为离开作用域而消失了
(3)用父类指向一个子类对象,析构函数没有实现多态
- class A
- {};
- int main()
- {
- A *p = new A;//没有释放
- return 0;
- }
class A
{};
int main()
{
A *p = new A;//没有释放
return 0;
}
(2)指针是一个局部变量,在释放内存之前,因为离开作用域而消失了
- class A
- {};
- void Test()
- {
- A *p = new A;
- }
- int main()
- {
- //无法释放
- return 0;
- }
class A
{};
void Test()
{
A *p = new A;
}
int main()
{
//无法释放
return 0;
}
(3)用父类指向一个子类对象,析构函数没有实现多态
- class A
- {};
- class B:public A
- {
- int x;
- };
- void Test()
- {
- A *p = new A;
- }
- int main()
- {
- A *p = new B;//只释放了基类所占用的空间,x所占用的空间没有释放
- delete p;
- return 0;
- }
class A
{};
class B:public A
{
int x;
};
void Test()
{
A *p = new A;
}
int main()
{
A *p = new B;//只释放了基类所占用的空间,x所占用的空间没有释放
delete p;
return 0;
}
三、堆
1.访问堆中成员的两种方式
访问堆中成员有两种方式,它们是等价的:A *p = new A();
1)(*p).get(); 2)p->get
例:
- class A
- {
- int x;
- public:
- A(int i):x(i){}
- int get(){return x;}
- };
- int main()
- {
- A *p = new A(1), *q = new A(2);
- cout<<(*p).get()<<' '<<q->get()<<endl;
- return 0;
- }
class A
{
int x;
public:
A(int i):x(i){}
int get(){return x;}
};
int main()
{
A *p = new A(1), *q = new A(2);
cout<<(*p).get()<<' '<<q->get()<<endl;
return 0;
}
输出:1 2