C语言查缺补漏(六)内存空间,指针

忽略点六:内存空间,指针

​ 介绍内存前,我们首先要知道一个由C/C++编译的程序占用的内存分为哪几个部分:

​ ——栈内存:C语言程序在编译时会被分配到内存的一片有限的连续区域,这部分内存会用于存储局部变量(函数中声明的变量),这部分连续区域被成为栈内存,又编译器自动分配和释放

​ ——堆内存:一般由程序员分配和释放,若程序员没有释放,则可能在程序结束时由操作系统回收(并不一定)。注意它与数据结构中的堆是两种东西!!

​ ——全局区(静态区,static):程序的全局变量和静态变量都存放在这里, 初始化存放在一块区域,未初始化的放在相邻的另一块区域(BSS),程序结束后由系统释放。注意!它既不是栈内存,也不是堆内存!

​ ——文字常量区:也叫字面量池区。常量字符串就是放在这里,由系统释放。

​ ——程序代码区:存放函数体的区域

​ 以下代码大家理解一手:

int a = 1;     //全局初始化区
int b;		   //全局未初始化区
int main() {
    char s[] = "abc";     //栈区
    char *p = "abc";      //“abc”在文字常量区(“abc”不是变量,也不是指针变量),p在栈区
    static c = 0;  		  //全局初始化区
    char *q = (char *) malloc (sizeof(char)); //q为栈区,申请的内容为堆区
}

​ 关于栈内存与堆内存:

​ ——栈内存:内存大小由系统预先设定,且是一块连续的内存空间,如果超出范围就是造成栈溢出,由于是系统分配的,所以速度较快,但程序猿无法控制。

​ ——堆内存:内存大小由程序猿手动申请,不一定连续,无内存范围限制(当然啦,肯定不能超过系统的有效内存),由于是程序猿分配的,一般速度较慢,但是用起来方便。(当然,如果使用不当的话,会造成严重的内存泄漏!!!而栈内存由于编译器自动回收内存,所以不会出现泄漏问题)

​ 我们由上边知道了堆内存是需要程序猿申请和释放的。那么通过什么方法申请呢?用什么头文件呢?

​ ——关于头文件,sodlib.h头文件与malloc.h都有封装的相关申请与释放堆内存的函数,所以两个选择任意一个即可

​ ——关于方法,申请有两个函数

一个是malloc函数,它的格式为:
int *p = (int *) malloc (n * sizeof (int));   

​ sizeof (int)表示n个整形变量所需内存空间大小

​ malloc (sizeof (int))表示申请该大小的内存空间,返回值为void型的指针

​ (int *)表示强制转换成int类型的指针

另一个是calloc函数,它个格式为:
int *p = (int *) calloc (n, sizeof(int));

​ 该代码意义同malloc一致,至于两者的区别,malloc申请后不初始化,而calloc申请后全部初始化为0

​ ——释放有一个函数free,它的用法如下

free(p);	//将p所指向的堆内存空间释放回系统
p = NULL;	//为避免错误使用p指针碰触已释放的内存,应设置为 p = NULL    

​ 以上就是内存空间的申请和释放,可能会有童鞋说还有new,delete,这些属于C++中的内容,等到C++查缺补漏时再总结~

​ 前一篇博文探究了指针作参的情况,这篇博文来研究一下指针的指针

​ 废话不多说,上代码:

int a = 1;
int *p = &a;
int **q = &p;

​ 在上面代码中:

​ 对于第一行来说:a是int类型变量

​ 对于第二行来说:p为变量a的地址(&a),而*p为a的值

​ 对于第三行来说,q为指针变量p的地址,也就是&p,而*q为p的值,也就是a的地址(&a)

​ 因此:*q = p = &a q = &p

​ 就是酱紫~

转载请注明出处!!!

如果有写的不对或者不全面的地方 请指正! 谢谢~

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/82928077