- #include<stdio.h>
- int main()
- {
- #if 0
- int *p=5;
- printf("-----------\n");
- //printf("*p=%d\n",*p); //编译、运行可以通过,但是加上输出时会出段错误
- //printf("p=%x\n",p);
- #endif
- #if 0
- int a=5;
- int *p=&a; //正确定义方法,p指向a的地址
- printf("*p=%d\n",*p);
- printf("p=%x\n",p);
- #endif
- #if 0
- int *p;
- *p=5;
- //printf("-----------\n"); //编译可以通过,运行出段错误
- //printf("*p=%d\n",*p);
- //printf("p=%x\n",p);
- #endif
- #if 0
- char *c={'a'};
- *c='t'; //编译通过,运行出段错误 *c指向有一个元素的数组,指针并没有分配空间
- #endif
- #if 0
- char c[]={'a'};
- c[0]='t'; //编译,运行可以通过。c[]局部数组,有空间,对应内存中的栈
- #endif
- }
由C/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack): 由编译器自动分配释放,存放函数的参数值,局部变量等。其操作方式类似于数据结构中的栈。
2、堆区(heap): 一般由程序员分配释放(malloc/free、new/delete), 若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(static): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后由系统释放。
4、文字常量区: 常量字符串就是放在这里的, 程序结束后由系统释放。
5、程序代码区: 存放函数体的二进制代码。
Example:
int a = 0; // 全局初始化区
char *p1; // 全局未初始化区
main()
{
int a; // 栈区
char s[] = "abc"; // 栈区
char *p2; // 栈区
char *p3 = "123456"; // 123456\0在常量区,p3在栈上。
static int c =0; // 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); // 分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); // 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
有一点必须知道,当一个函数调用完返回后它会释放该函数中所有的栈空间。栈是由编译器自动管理的,不用你操心。堆是动态分配内存的,并且你可以分配使用很大的内存。但是用不好会产生内存泄漏。并且频繁地malloc和free会产生内存碎片(有点类似磁盘碎片),因为C分配动态内存时是寻找匹配的内存的。而用栈则不会产生碎片。在栈上存取数据比通过指针在堆上存取数据快些。一般大家说的堆栈和栈是一样的,就是栈(stack),而说堆时才是堆heap。
阅读(1092) | 评论(0) | 转发(0) |