C语言学习(八)typedef 虚拟内存 malloc/free

news2024/11/28 4:48:56

目录

  • 一、typedef 类型重定义
    • (一)使用
    • (二)define和typedef的区别
      • 1. 编译处理的阶段不同
      • 2. 功能不同
  • 二、虚拟内存
    • (一)虚拟内存分布
    • (二)内存分布
      • 1. 静态分配
      • 2. 动态分配
  • 三、malloc/free函数
    • (一) malloc函数
        • (1)定义
        • (2)使用
    • (二) free函数
    • (三) 使用
  • 四、内存泄漏
    • (一)概念
    • (二) 规避方法
    • (三)示例

一、typedef 类型重定义

(一)使用

typedef <数据类型> <标识符>

typedef int int32_t; 

typedef int arr_t[2][3];//两行三列的二维数组类型

typedef int(*fun_t)(int,int); //定义int(*)(int,int)类型

(二)define和typedef的区别

1. 编译处理的阶段不同

define在预处理阶段,typedef参与编译阶段

  • 注:编译的过程:
  • 预处理:展开头文件,删除注释,宏替换
    gcc - E hello.c -o hello.i
    hello.i 就是预处理文件。预处理不会检查语法错误。
  • 编译:语法统计,词法统计,语义分析
    gcc -S hello.i -o hello.s
    生成一个汇编文件。编译会检查语法错误
  • 汇编
    gcc -c hello.s -o hello.o
    生成一个二进制文件。
  • 链接:链接库文件,生成一个可执行的二进制文件
    gcc hello.o -o hello

2. 功能不同

define是字符串原样替换;typedef是用于类型重定义

二、虚拟内存

(一)虚拟内存分布

图片1

  • 内核空间:(0xcccc cccc~0xffff ffff)程序共用,不允许用户使用
  • 栈区:空间自动申请,自动释放;向下生长
    主要存放局部变量,未初始化时是乱值。
    (栈区空间,windows是2M,可以调至10M;在Linux中是8M)
  • 堆区:手动申请,手动释放;向上生长
    malloc / realloc / calloc
    (堆区空间,大概1.9G)
  • 常量区
    .bss段:未初始化的全局变量
    .data段 :初始化的全局变量
    .readonly段:只读段
    .text段 (代码区):程序代码

mmu固件:将虚拟内存映射到物理内存中。

eg:分析以下数据存放在内存中的位置:number1 , number2, number3, number4, p1, p2 ,p3 *p1,*p3, function, *p2

include <stdio.h>

int number1;  
未初始化的全局变量:常量区-->.bss段
int number2 = 10;   
初始化的全局变量:常量区-->.data段
字面量值10存储在常量区。

int function() 代码:常量区-->代码区
{
    int number3 = 30;  初始化的局部变量:栈区
    int number4;  未初始化的局部变量:栈区
}
int main() 代码:常量区-->代码区
{
    char * p1 = "hello world";  p1 局部变量:栈区
    *p1:常量区-->readonly段
    char p2[]= "abc"  p2 局部变量:栈区
    *p2:栈区
    char *p3 = (char *)malloc(20);   
    p3 局部变量:栈区; p3指向的内存空间 堆区
    free(p3);
    p3 = NULL;
}
  • 注:当程序加载到内存中时,number2的内存空间(在.data段)会被分配,
    并且其值会被初始化为10(这个值来源于常量区,但在运行时它是存储在.data段中的)。

(二)内存分布

C语言分配内存的方法:静态分配 动态分配

1. 静态分配

在编译节点的时候,已经确定了分配空间大小。
eg:int a=10; intarr[2][2];

2. 动态分配

编写程序时,不确定要申请多少空间,在执行时根据需要进行的空间分配。
eg:malloc分配的空间就属于动态分配。

三、malloc/free函数

(一) malloc函数

(1)定义
头文件(标准库文件):
#include <stdlib.h>

函数原型:
void *malloc(size_t size);

函数功能:
 在内存中(堆)区中开辟指定大小的地址连续的空间。
 
函数参数:
 size_t  无符号整型,size表示开辟多少字节空间。

函数返回值:
 成功,返回开辟空间的首地址;失败,返回一个NULL
(2)使用

申请空间为一段连续的空间:
① 可以使用下标进行访问
②可以通过指针进行访问

(二) free函数

头文件(标准库文件):
#include <stdlib.h>

函数原型:
void free(void *ptr);

函数功能:
 释放手动申请的空间。
 
函数参数:
 void* ptr: malloc/realloc/calloc申请的空间的首地址
  • 注:释放已经释放过的指针会造成程序错误。
  • 但是指针指向NULL时,释放多次都不会报错。

(三) 使用

#include <stdio.h>
#include <stdlib.h>

int main()
{
	//申请空间
	int *p =mymalloc(20);
	if(!p)
	{
		printf("create fail!\n");
		return -1;
	}
	//向空间内写值
	*p = 10;
	*(++p)= 20;
	//读值
	for (int i=0;i<20;i++)
	{
		printf("%d ",*(p+i));
	}
	//释放空间
	free(p);
	p = NULL;
	/*释放完空间后,将指针指向NULL
	/指向NULL后,再次释放不会报错*/
}

int mymalloc(int size)
{
	int *p = (int *)malloc(size);
	if(!p)
	{
		printf("fail!\n");
		return -1;
	}else
	{
		prnintf("sucess:%p\n",p);
	}
	return 0;
}

eg
功能需求
定义一个函数: create 功能: 在内存中申请n个字节大小. n是一个参数.
这个函数的返回值是指针类型.
set(指针)函数 功能: 从键盘中输入n个值, 将N个值存入 create创建的空间中.
sort函数():使用冒泡排序对这n个值进行排序.
max函数(): 返回空间中的最大值
min函数(): 返回空间中的最小值.、

代码实现

#include <stdio.h>
#include <stdlib.h>

int min(int *arr,int len);
int max(int *arr,int len);
void sort(int *arr,int len);
void set(int *a,int n);
int* create(int size);
void show(int *arr,int size);
void create_noReturn(int **p,int size);//使用二级指针传参

int main()
{
    int size;
    //申请空间
    printf("please input size:");
    scanf("%d",&size);
	/*** 
	* int *p = NULL;
	* create_noReturn(&p,size);
	***/
    int *p = create(size);//20个字节,5个int
    //判断p空间是否申请成功
    if(p!)
    {
    	printf("create fail!!");
    	return -1;
    }
    //向空间内写值
    set(p,size);
    //排序,读值
    sort(p,size);
    show(p,size);

    printf("MAX:%d\n",max(p,size));
    printf("MIN:%d\n",min(p,size));
    //释放空间
    free(p);
    p = NULL;
}
void show(int *p,int size)
{
    for(int i=0;i<5;i++)
    {
        printf("%d ",*(p+i));
    }
    putchar(10);
}
//申请n字节大小,返回值是申请空间的指针
int* create(int size)
{
    int *p = (int *)malloc(4*size);
    if(!p)
    {
        printf("fail!\n");
        return NULL;
    }
    return p;
}
//无返回值的空间分配
void create_noReturn(int **p,int size)
{
      int s=4*size;
      *p =(int*)malloc(s);
  }   

void set(int *a,int n)
{
    for(int i=0;i<n;i++)
    {
        printf("please input %d num:",i+1);
        scanf("%d",a+i);                                                                                                                                                                                                                                                                                                       
    }
}

//排序
void sort(int *arr,int len)
{
    int flag = 0;
    for(int i=0;i<len-1;i++)
    {
        flag = 0;
        for(int j=0;j<len-i-1;j++)
        {
            if(*(arr+j)>*(arr+j+1))
            {
                int temp=*(arr+j);
                *(arr+j)=*(arr+j+1);
                *(arr+j+1)=temp;

                flag=1;
            }
        }
        if(!flag) break;
    }
}

//最大值
int max(int *arr,int len)
{
    int max = *arr;
    for(int i=0;i<len;i++)
    {
        if(max<(*(arr+i)))
            max = *(arr+i);
    }
    return max;
}

//最小值
int min(int *arr,int len)
{
    int min = *arr;
    for(int i=0;i<len;i++)
    {
        if(min>(*(arr+i)))
            min = *(arr+i);
    }
    return min;
}

四、内存泄漏

(一)概念

在C语言中调用malloc/calloc/realloc函数时,申请内存后没有调用free函数进行释放内存,导致内存越用越少。

(二) 规避方法

当空间使用完毕后,及时释放内存。

(三)示例

int main()
{
	int * p =malloc(20);
	p = malloc(20);
	
	free(p);
	return 0;
}

此时p指向第二次申请的内存空间,没有指针指向第一次申请的内存空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1668583.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用canvas在图片上进行标注,以下代码不起作用,着实被坑到了(文末附完整代码)

今天发现一个有意思的问题&#xff1a; 如何使用canvas在图片上进行如下的标注&#xff0c;以下代码不起作用,如何修改 原始代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name&quo…

理解进程的基本概念

1. 什么是进程 进程&#xff0c;即执行中的程序 进程 程序执行 在计算机中&#xff0c;每一个运行的exe程序&#xff0c;就是一个进程 2.为什么会有进程 早期&#xff0c;操作系统只有一个程序&#xff0c;这样效率是很低的。为了提高CPU的利用率&#xff0c;人们将多个程…

时间复杂度的简单讲解

小伙伴们大家好&#xff0c;我们又见面了&#xff0c;这次我们直接进入正题 时间复杂度的概念 时间复杂度的定义&#xff1a;在计算机科学中&#xff0c; 算法的时间复杂度是一个函数 &#xff0c;它定量描述了该算法的运行时间。一 个算法执行所耗费的时间&#xff0c;从理论…

Hadoop-未授权访问-内置配合命令执行RCE

一、Hadoop常见端口及配置文件 Hadoop中有多种端口&#xff0c;这些端口用于不同的服务和通信。以下是Hadoop中常见的端口以及它们的用途&#xff1a; NameNode Web界面端口 (默认: 9870)NameNode 对客户端服务端口 (默认: 8020)Secondary NameNode Web界面端口 (默认: 9868)…

每日OJ题_贪心算法四⑤_力扣354. 俄罗斯套娃信封问题

目录 力扣354. 俄罗斯套娃信封问题 解析代码1_动态规划&#xff08;超时&#xff09; 解析代码2_重写排序贪心二分 力扣354. 俄罗斯套娃信封问题 354. 俄罗斯套娃信封问题 难度 困难 给你一个二维整数数组 envelopes &#xff0c;其中 envelopes[i] [wi, hi] &#xff0…

物联网杀虫灯—新型的环保杀虫设备

型号推荐&#xff1a;云境天合TH-FD2S】物联网杀虫灯是一种新型环保杀虫设备&#xff0c;其中风吸式太阳能杀虫灯作为其一种特殊类型&#xff0c;展现了独特的工作原理和优势。 风吸式太阳能杀虫灯以太阳能电池板为电源&#xff0c;白天储存电源&#xff0c;晚上为杀虫灯提供电…

资产公物仓管理系统|实现国有资产智能化管理

1、项目背景 资产公物仓管理系统&#xff08;智仓库DW-S201&#xff09;是一套成熟系统&#xff0c;依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 项目设计原则 方案对公物仓资…

Java 守护线程 ( Daemon Thread )详解

在Java中&#xff0c;线程分为两类&#xff1a;用户线程(User Thread)和守护线程(Daemon Thread)。守护线程是后台线程&#xff0c;主要服务于用户线程&#xff0c;当所有的用户线程结束时&#xff0c;守护线程也会自动结束&#xff0c;JVM会随之退出。守护线程的一个典型例子是…

docker(四):数据卷

数据卷 卷的设计目的就是数据的持久化&#xff0c;完全独立于容器的生存周期&#xff0c;因此Docker不会在容器删除时删除其挂载的数据卷。 1、docker run docker run -it --privilegedtrue -v /宿主机绝对路径目录:/容器内目录 镜像名2、挂载注意事项 --privilegedtru…

贪吃蛇(c实现)

目录 游戏说明&#xff1a; 第一个是又是封面&#xff0c;第二个为提示信息&#xff0c;第三个是游戏运行界面 游戏效果展示&#xff1a; 游戏代码展示&#xff1a; snack.c test.c snack.h 控制台程序的准备&#xff1a; 控制台程序名字修改&#xff1a; 参考&#xff1a…

【考研数学】汤家凤“免单“数学题被吐槽‘太难’,老汤回应「怎么还有脸笑」,网友:这些题有毒!

我看了汤家凤老师出的几道题&#xff0c;实际上对于考研的同学来说&#xff0c;确实是送分题 第一个是三角函数变换中的万能公式&#xff1b;第二个e^x的泰勒展开公式&#xff1b;第三个是第一类重要极限。只要复习过&#xff0c;那基本上都能正常做出来。 至于汤家凤老师说「…

C#中数组与列表,集合等的联系

C#中&#xff0c;所有数组都自动继承于System.Array这个抽象类&#xff0c;数组都为引用类型&#xff0c; 所有对数组的更新都会导致源数组的元素值的篡改。 而所有集合的根都来自可枚举接口IEnumerable 数组有三种样式&#xff1a; 数组的Rank&#xff08;秩&#xff09;属…

纯血鸿蒙APP实战开发——Grid和List内拖拽交换子组件位置

Grid和List内拖拽交换子组件位置 介绍 本示例分别通过onItemDrop()和onDrop()回调&#xff0c;实现子组件在Grid和List中的子组件位置交换。 效果图预览 使用说明&#xff1a; 拖拽Grid中子组件&#xff0c;到目标Grid子组件位置&#xff0c;进行两者位置互换。拖拽List中子…

【数据结构】环状链表OJ题

✨✨✨专栏&#xff1a;数据结构 &#x1f9d1;‍&#x1f393;个人主页&#xff1a;SWsunlight 一、OJ 环形链表&#xff1a; 快慢指针即可解决问题: 2情况&#xff1a; 快指针走到结尾&#xff08;不是环&#xff09;快指针和尾指针相遇&#xff08;是环的&#xff09; …

macos使用yarn创建vite时出现Usage Error: The nearest package directory问题

步骤是macos上使用了yarn create vite在window上是直接可以使用了yarn但是在macos上就出现报错 我们仔细看&#xff0c;它说的If /Users/chentianyu isnt intended to be a project, remove any yarn.lock and/or package.json file there.说是要我们清除yarn.lock和package.js…

OGG几何内核-网格化的改进

OGG社区于4月19日发布了OGG 1.0 preview版本。相对于OCCT 7.7.0有很多改进&#xff0c;目前在持续研究中。最近测试了一下网格化&#xff0c;确实有很好的改进。对比展示如下&#xff1a; 几何内核&#xff1a; OGG 1.0 preview 几何内核&#xff1a;OCCT 7.7.0 采用OCCT几何内…

线程同步--条件变量,信号量

生产者和消费者模型 案例 /*生产者消费者模型&#xff08;粗略的版本&#xff09; */ #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h>// 创建一个互斥量 pthread_mutex_t mutex;struct Node{int num;struct Node …

【ALM】ALM解决方案系列:质量保证

1软件的质量管理现状与痛点 在软件开发中&#xff0c;质量被视为软件产品的生命。保证软件质量&#xff0c;是贯穿整个软件生命周期的重要问题。如果在软件开发早期忽视质量管理&#xff0c;会导致软件项目管理出现问题。因此&#xff0c;重视并规范软件管理在软件项目管理中起…

[论文笔记]Corrective Retrieval Augmented Generation

引言 今天带来论文Corrective Retrieval Augmented Generation的笔记&#xff0c;这是一篇优化RAG的工作。 大型语言模型(LLMs) inevitable(不可避免)会出现幻觉&#xff0c;因为生成的文本的准确性不能仅仅由其参数化知识来确保。尽管检索增强生成(RAG)是LLMs的一个可行补充…

带你手撕红黑树! c++实现 带源码

目录 一、概念 二、特性 三、接口实现 1、插入 情况一&#xff1a;p为黑&#xff0c;结束 情况二&#xff1a;p为红 1&#xff09;叔叔存在且为红色 2&#xff09;u不存在/u存在且为黑色 &#xff08;1&#xff09;p在左&#xff0c;u在右 &#xff08;2&#xff09;…