标签:
在C语言中,根据数据在内存中存在的时间(生存期)不同,将内存空间分为三个区:
1.程序区:用于存储程序的代码,即程序的二进制代码;
2.静态存储区:用于存储全局变量和静态变量,这些变量的空间在程序编译时就已经分配好了;
3.动态存储区:用于在程序执行时分配的内存,又分为:堆区(heap)和堆栈区(stack)两种。
堆区:用于动态内存分配,程序运行时由内存分配函数在堆上分配内存。在C语言中,只要使用指针才能动态的分配内存。
堆栈区:在函数执行时,函数内部的局部变量和函数参数的存储单元的内存区域,函数运行结束时,这些内存区域会自动释放。在数据结构-栈的应用时提到栈用于实现函数调用,系统需要为函数调用创建变量存储区,这里的存储区就是从堆栈区申请,堆栈区的栈就是表示栈使用。
指针实例:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 int *num = NULL; 6 int *x, y[] = {12, 22,32}, z = 100; 7 8 //下面演示,指针既可充当变量、也可充当数组 9 x=&z; //整型变量的地址赋给x 10 printf("*x=%d, x[0]=%d\n", *x, x[0]);//100,100
&z表示将z的地址付给x
*x表示去当前指针的内容
11 12 x = y; //数组的地址赋给x 13 printf("*x=%d, x[ 0]=%d, x[ 1]=%d, x[2]=%d\n", *x, x[0], x[1], x[2]);//12 12 22 32
将数组的首地址赋给x 14 15 x = y + 1; //数组的第二位地址赋给x 16 printf("*x=%d, x[-1]=%d, x[ 0]=%d, x[1]=%d\n", *x, x[-1], x[0], x[1]);//22 12 22 32 17 18 x = y + 2; //数组的第三位地址赋给x 19 printf("*x=%d, x[-2]=%d, x[-1]=%d, x[0]=%d\n", *x, x[-2], x[-1], x[0]);//32 12 22 32 20 21 return 0; 22 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main(void) 5 { 6 int *p, i; 7 8 p = (int *)malloc(6 * sizeof(int)) ; 9 if (p == NULL) { //判断是否为空 10 printf("内存分配出错!"); 11 exit(1); 12 } 13 14 for (i=0; i<6; i++) { 15 p++; 16 *p = i; 17 printf("%2d", *p); 18 } 19 printf("\n"); 20 21 free(p); //这句运行时出错 22 23 return 0; 24 }
自己觉得这个程序指针使用方式可以换成以下这种:
#include <stdio.h> #include <stdlib.h> int main(void) { int *p, i; p = (int *)malloc(6 * sizeof(int)) ; if (p == NULL) { //判断是否为空 printf("内存分配出错!"); exit(1); } for (i=0; i<6; i++) { p = &i; printf("%2d", *p); p++; } printf("\n"); free(p); //运行这句是争取的 return 0; }
在函数内使用的指针动态分配了内存,用完后不释放。其理由是:函数运行结束后,函数内的所有变量全部消亡。这是错误的。动态分配的内存是在“堆”里定义,这个堆是系统使用的自由存储空间,只有等程序结束后才会销毁,并不随函数结束而消亡。
动态分配了内存的指针,用完后直接设置为NULL。其理由是:已经为NULL了,这就释放了。这也是错误的。指针可以任意赋值,而内存并没有释放;相反,内存释放后,指针也并不为NULL。
指针置为NULL,是表示指针指向空地址,但是指针依然占用内存,没有释放掉,可能会导致内存泄漏。
参考链接:
http://www.cnblogs.com/jiajinghai/archive/2011/11/09/2243709.html
http://www.quanxue.cn/jc_clanguage/CLang/Clang13.html
标签:
原文地址:http://www.cnblogs.com/x739400043/p/5839798.html