作用域

一个C语言变量的作用域可以是代码块 作用域,函数作用域或者文件作用域

代码块是{}之间的一段代码

同一个代码块不可以有重名变量

auto自动变量

一般情况下代码块内部定义的变量都是自动变量

也可以显示的使用aotu关键字

auto int i;

register寄存器变量

通常变量在内存当中,如果能把变量放到CPU的寄存器里面,代码执行效率会更高

寄存器变量存在于CPU,没有内存地址,不可以取地址(&)

register int i;

static静态变量

默认初始化为0

static变量在程序一开始时候加载到内存就已经存在,static初值只初始化一次

static int i = 0;

局部的静态变量

静态变量是指内存位置在程序执行期间一直不改变的变量,一个代码块内部的静态变量只能被这个代码块内部访问

全局的静态变量

代码块之外的静态变量在程序执行期间一直存在,但只能被定义这个变量的文件访问

全局变量

默认初始化为0

全局变量在程序加载时候就存在,一直到程序退出才销毁

全局变量的存储方式和静态变量相同,但可以被多个文件访问(extern)

外部变量与extern关键字

extern int i;

全局函数与静态函数

在C语言中函数默认都是全局的,使用关键字static可以将函数声明为静态

内存四区

内存分区可以大概分为四个区,代码区,静态区,栈区,堆区

代码区

代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的

存放程序代码指令,常量字符串

不可读写,只可以执行

代码区的地址可以通过函数指针来访问

静态区

所有的全局变量以及程序中的静态变量都存储到静态区,比较如下两段代码的区别

存放全局变量/常量和静态变量/常量

int a = 0;
int main()
{
static int b = 0;
printf("%p, %p\n", &a, &b);
return 0;
}
int a = 0;
static int b = 0;
int main()
{
printf("%p, %p\n", &a, &b);
return 0;
}

栈区

栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出

存放所有的自动变量,包括函数的形参都放到栈区

栈顶指针从高位向地位递减

C语言中,函数参数从右到左入栈

栈空间不可以定义可变数组,其原因是栈空间大小在编译时候就要确定

堆区

程序可以自由的在堆中存放任何变量

堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。

堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成

堆的分配和释放

malloc

使用关键字malloc可以在堆内存中开辟存储空间,一般使用memset将内存清零

malloc(1024);
memset(p, 0, 1024);

注:在使用malloc开辟内存使用完成后,必须使用free释放开辟的内存

int *p = (int *)malloc(sizeof(int));
···
free(p);

calloc

int *p = (int *)calloc(100, sizeof(int));//分配100个int

第一个参数是所需内存单元数量,第二个参数是每个内存单元的大小(单位:字节),calloc自动将分配的内存置0

realloc

用于内存的大小改变,自动释放原内存,保存新内存

int *p = (int *)malloc(1024);
memset(p, 0, 1024);
···
p = realloc(p, 2048);
realloc(NULL, 1024);
//等价于
malloc(1024);

C学习笔记-内存管理的更多相关文章

  1. c语言学习笔记.内存管理.

    内存: 每个程序的内存是分区的:堆区.栈区.静态区.代码区. 1.代码区:放置所有的可执行代码,包括main函数. 2.静态区:存放所有的全局变量和静态变量. 3.栈区:栈(stack),先进后出.存 ...

  2. JVM学习笔记-内存管理

    第一章 内存分配 1. 内存区域.     方法区和堆(线程共享),程序计数器 , VM栈 和 本地方法栈(线程隔离).     1) java虚拟机栈:线程私有.描写叙述的是java方法执行的内存模 ...

  3. 《深入理解 Java 虚拟机》学习笔记 -- 内存区域

    <深入理解 Java 虚拟机>学习笔记 -- 内存区域 运行时数据区域 主要分为 6 部分: 程序计数器 虚拟机栈 本地方法栈 Java 堆 方法区 如图所示: 1. 程序计数器(线程私有 ...

  4. JVM学习笔记——内存结构篇

    JVM学习笔记--内存结构篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存结构部分 我们会分为以下几部分进行介绍: JVM整体介绍 程序计数器 虚拟机栈 本地方法栈 堆 方法 ...

  5. Linux内核笔记--内存管理之用户态进程内存分配

    内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...

  6. java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 说起垃圾收集(Garbage Collection,下文简称GC),大部分人都把这项 ...

  7. java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)

    概述 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝又 ...

  8. python学习Day9 内存管理

    复习 :文件处理 1. 操作文件的三步骤:-- 打开文件:此时该文件在硬盘的空间被操作系统持有 |  文件对象被应用程序持用 -- 操作文件:读写操作 -- 释放文件:释放操作系统对文件在硬盘间的持有 ...

  9. RT-Thread学习2 —— 内存管理学习记录

    RT-Thread学习2 -- 内存管理学习记录1 小内存管理算法(mem.c) 1. 小内存管理法: 小内存管理算法是一个简单的内存分配算法.初始时,它是一块大的内存.当需要分配内存块时,将从这个大 ...

随机推荐

  1. Liquibase使用(转)

    文章目录 介绍快速使用Springboot中引入依赖配置日志文件ChangeLog编写变更记录ChangeSetMaven中引入依赖配置liquibase.properties编写变更记录Change ...

  2. VC:检测网络连接的方法

    方法一: #include "stdafx.h" #include "windows.h" #include <Sensapi.h> #includ ...

  3. Confluence 6 移动一个文件到其他页面

    你需要同时具有 添加页面(Add Page),添加附件(Add Attachment)和删除附件(Remove Attachment)空间权限来移动一个附件文件到其他页面. 希望修改附件附加的页面到其 ...

  4. delphi请求http接口并上传附件

    实现附件的上传:需要使用TIdMultiPartFormDataStream控件, uses IdMultipartFormData; 例子: procedure TClientForm.Button ...

  5. 【IOI2018】机械娃娃

    看到的时候感到很不可做,因为所有的开关都要状态归零.因此可以得到两分的好成绩. --然后 yhx-12243 说:这不是线段树优化建图吗? 于是我获得了启发,会做了-- 还不是和上次一样,通过提示做出 ...

  6. ZAP-Queries【luogu3455】

    题目大意 有不超过\(50000\)个询问,每次询问有多少正整数对\(x\),\(y\),满足\(x\leqslant a\),\(y \leqslant b\),并且\(gcd(x,y)=c\).其 ...

  7. 设置Linux自启服务以及优先级

    一. 启动优先级 今天有一台服务器没有正常启动,原因是有一个服务没有启动起来,因为A服务需要B服务启动之后才能正常启动,所以需要调整A,B服务的启动顺序.在网上查找了一些资料,总结了一下,以备以后需要 ...

  8. QTableWidget懒加载(动态加载)实现

    在QTableWidget中加入一行行的数据,如果数据数量过多,滚动起来就会卡顿,插入数据时也会影响性能,为了解决这个问题,采用懒加载的方式,只在界面上显示10几条数据,填满界面.同时增加而外的竖直滚 ...

  9. javascript 取小数点后几位四种方法

    javascript 取小数点后几位方法总结 Javascript取float型小数点后两位,例22.123456取成22.12,如何做? 1.通过substring截取. function getn ...

  10. Java操作符——i++ 和 ++i的区别

    问题:前置自增和后置自增的区别 Code-后置自增 public class Test { public static void main(String[] args) { int a = 2; in ...