学习笔记12-C语言-堆内存、字符串

什么是堆内存:

是进程中的一个内存段(text\data\bss\heap\stack),由程序猿手动控制。
特点是足够大,缺点是使用麻烦

为什么要使用堆内存:

1、随着程序的复杂,数据会越来越多。
2、其他的内存段的申请和释放不受控制,堆内存的申请释放受程序猿控制

如何使用堆内存:

注意:在C语言中没有控制堆内存的语句,只能使用C标准库中的函数void *malloc(size_t size);malloc(4);
功能:从堆内存中申请size个字节的内存,申请的内存中存储的内容不确定
size: 表示要申请的字节数大小
返回值:成功时返回成功申请到的内存的首地址,失败时返回NULLvoid free(void *ptr);
功能:释放一块内存,NULL可以释放,但是不能连续释放和释放非法地址
ptr:要释放的堆内存的首地址
注意:释放的只是使用权,不会专门去清理全部的数据void *calloc(size_t nmemb,size_t size)
功能:从堆内存中申请nmemb块大小为size字节的内存,申请到的内容块会被初始化为0
注意:申请到的依然是一块连续的内存void *realloc(void *ptr,size_t size)
功能:改变已有的内存的大小,在原来内存大小的基础上调大或调小
ptr:想要改变大小的内存的首地址
size:表示调整后的大小
返回值:是调整后的内存块的首地址,一定要重新接收返回值,因为可能不是在原来内存块的基础上调整的。如果无法在原来的基础上进行调整:1、申请一块新的符合大小要求的内存块2、把原内存块中的数据拷贝到新内存块中3、把新内存块的首地址返回

malloc内存管理机制:

当首次使用malloc申请内存时,malloc会向操作系统申请内存,操作系统会直接给malloc分配33页(1页=4096字节)内存交给malloc管理。
但是不意味着你可以越界访问,因为malloc可能会把使用权分配给“其他人”,这就会导致脏数据。每个内存块之间都会有一些空隙(4~12个字节),这些空隙一些是为了内存数据对齐,其中一定会有4个字节是用于记录malloc维护信息,
这些维护信息决定了malloc下次分配内存的位置,以及借助这个维护信息计算出每个内存块的大小,当这些信息被破坏时,会影响下一次和freemalloc函数的调用

使用堆内存要注意的问题:

内存泄露:内存无法再次使用,也无法被释放,而再次使用时只能重新申请,然后重复以上操作,最后导致日积月累后系统中可以使用的内存越来越少注意:程序一旦结束后,属于该程序的所有资源都会被操作系统回收如何尽量避免内存泄漏:谁申请谁释放,谁知道该释放谁释放如何判断定位内存泄漏:1、查看内存使用情况windows下看任务管理器,Linux下使用ps -aux命令查看内存使用情况)2、使用代码分析工具来检查malloc和free的调用情况3、包装malloc和free函数,记录申请释放内存信息到日志中

内存碎片:

已经释放但也无法继续使用的内存叫做内存碎片,是由于申请和释放的时间不协调导致的,是无法避免只能尽量减少如何减少内存碎片:1、尽量使用栈内存2、不要频繁的申请和释放内存3、尽量申请大块内存自己管理s

内存清理函数:

#include<strings.h>
void bzero(void *s,size_t n);
功能:把内存块按字节设置为0
s:内存块的首地址
n: 要清理的内存块的字节数#include<string.h>
void *memset(void *s,int c,size_t n);
功能:把内存块按字节设置为字符c
s:内存块的首地址
c:xiangyao设置的字符的ASCII码值
n: 要清理的内存块的字节数
返回值:返回设置成功后内存块的首地址

堆内存定义二维数组:

指针数组:定义n*m的二维数组类型* arr[n];for(int i=0;i<n;i++){arr[i] = malloc(sizeof(类型)*m);}注意:每一行m值可以不同,所以可以定义不规则的二维数组数组指针:定义m*n的二维数组类型(*arrp)[n] = malloc(sizeof(类型)*n*m);注意:所谓的多维数组都是用一维数组来模拟的

练习1:计算出100~10000之间的所有素数,结果要存储再堆内存中,不能浪费内存

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<stdbool.h>bool is_ss(int n)
{for(int i=2;i<=sqrt(n);i++){if(n%i==0)return false;}return true;
}int main(int argc,const char* argv[])
{int* p=NULL;int cnt=0;for(int i=100;i<=10000;i++){if(is_ss(i)){p = realloc(p,(cnt+1)*sizeof(int));p[cnt++] = i;}}for(int i=0;i<cnt;i++){printf("%d ",p[i]);}free(p);p=NULL;return 0;
}

字符串

字符:在计算机中,字符是以整数形式存储再内存中,当需要显示为字符时,会根据ASCII码表中的对应关系来显示出相应的符号与图案。'\0'    0'0'     48'A'     65'a'     97字符的输入:scanf("%c",&ch);ch = getchar();字符的输出:printf("%c",ch);putchar(ch);
串:是一种数据结构,是由一组连续的若干个相同类型的数据组成,末尾有一个结束标志。对于这种数据结构的处理都是批量性的,从开头位置开始直到结束标志为止。字符串:由字符组成的串型结构,结束标志是'\0'字符串的输入:scanf  %s   地址注意: 不能接受空格char *gets(char *s);功能:输入字符串,并可以接收空格返回值:链式调用(把一个函数的返回值当作另一个函数的参数)char *fgets(char *s,int size,FILE *stream);功能:可以设置输入的字符串的长度为size-1,超出部分不接受,会为'\0'预留位置。注意:如果输入的字符数不足size-1个,,最后的'\n'会一起接受char str[20]={};fgets(str,20,stdin);字符串的输出:printf  %s int puts(const char *s);功能:输出一个字符串,会在末尾自动添加一个\n返回成功输出的字符个数

字符串的存在形式:

字符数组: char str[10] = 由char类型组成的数组,要为'\0'预留位置使用的是栈内存,所以数据可以修改
字符串字面值:“Hello World!”"由双引号包含的若干个字符",会在末尾隐藏一个\0字符串字面值是以地址形式存在的,数据是存储再代码段,如果修改则会产生段错误const char* p = “字符串字面值”;sizeof("strstr");结果 = 字符个数+两个一摸一样的字符串字面值在代码段中只存储一份常用方式: 字符数组[]="字符串字面值";会自动为'\0'预留位置注意:在赋值完成后字符串就存在了两份,一份存储在代码段,一份存储在栈内存(可修改)

练习2:实现一个函数,判断字符串是否是回文数

#include<stdio.h>
#include<string.h>
#include<stdbool.h>bool is_hw(const char* n)
{int i,j;size_t len = strlen(n)-1;for(i=0;i<len/2;i++){if(n[i] != n[len-i])return false;}return true;
}int main(int argc,const char* argv[])
{char num[255]={};gets(num);if(is_hw(num))printf("yes");else printf("no");
}

练习3:实现一个函数,把由数字字符组成的字符串转换为整数

#include<stdio.h>
#include<string.h>
void to_num(char* n,int l)
{for(int i=0;i<=l;i++){n[i] -= '0';}
}int main(int argc,const char* argv[])
{char num[10]={};gets(num);int len =strlen(num)-1;to_num(num,len);for(int i=0;i<=len;i++){printf("%d ",num[i]);}
}

练习4:实现一个函数,把字符串逆序、

#include<stdio.h>
#include<string.h>void change(char* n,int l)
{int i,j;for(i=0,j=l;j>i;i++,j--){char temp=n[j];n[j]=n[i];n[i]=temp;}
}int main(int argc,const char* argv[])
{char str[100]={};gets(str);int len=strlen(str)-1;change(str,len);puts(str);
}

练习5:实现一个抽奖函数,10人名单,按随即顺序列出人名

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>int main(int argc,const char* argv[])
{srand(time(NULL));char* name[10]={"张三","李四","王五","赵六","刘七","周八","srh","baba","erzi","yeye"};for(int i=0;i<10;){int index = rand()%10;if(NULL != name[index]){printf("第%d名:%s\n",i+1,name[index]);name[index]=NULL;i++;}}}

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

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

相关文章

学习笔记13-C语言-字符串函数、缓冲区

字符串的常用函数: #include<string.h> size_t strlen(const char* s); 功能&#xff1a;计算字符串长度&#xff0c;但是结果不包括\0 返回值&#xff1a;返回字符串中字符的个数size_t str_len(const char* str) {assert(NULL ! str);const char* tmp str;while(*tmp…

Oracle数据库里面查询字符串类型的字段不为空和为空的SQL语句:

摘要&#xff1a;近期项目中&#xff0c;在做高级查询的时候有个条件是根据选择的字段&#xff0c;然后再选择字段的值为空和不为空做查询&#xff0c;在写SQL语句的时候费了很长时间&#xff0c;现在记录一下&#xff0c;方便日后查看&#xff1a; 一&#xff1a;查询字符串类…

学习笔记14-C语言-小项目-通讯录

通讯录&#xff1a; 要求&#xff1a; 姓名&#xff0c;性别、电话&#xff0c;最多储存50个联系人 功能&#xff1a;1、添加联系人2、按名字删除联系人3、按姓名修改联系人信息4、查找联系人&#xff0c;可通过电话&#xff0c;名字查找&#xff0c;支持模糊查找5、显示所有联…

学习笔记15-C语言-预处理指令、条件编译、头文件

预处理指令&#xff1a; 程序猿编写的代码不是标准C代码&#xff0c;并不能被真正的编译器索编译&#xff0c;需要一段程序把代码翻译一下。 翻译的过程叫做预处理&#xff0c;被翻译的代码叫做预处理指令&#xff0c;以#开头的都是预处理指令查看预处理的过程&#xff1a;gcc…

学习笔记16-C语言-小项目-使用Makefile完成2048

Makefile: Makefile是一系列编译指令组成的可执行文本&#xff0c;也叫做编译脚本。 在终端执行make命令会自动执行Makefile脚本中的编译命令&#xff0c; 而且它还可以根据文件的最后修改时间来判断哪些文件是否需要重新编译、哪些文件不需要重新编译&#xff0c;从而大大提高…

学习笔记17-C语言-结构、联合、枚举

结构&#xff1a; struct 结构是由程序猿自己设计的一种数据类型&#xff0c;用于描述一个事务的各项数据&#xff0c;由若干个不同的基础数据类型组成。设计结构&#xff1a;struct 结构体名{类型 成员名&#xff1b;...}&#xff1b;定义结构体变量struct 结构体名 变量名&a…

Maven 3.0.5 安装和配置:

摘要&#xff1a;现在的Web项目越来越多的都用maven管理了&#xff0c;所以我也抽时间学习学习&#xff0c;为了赶上时代&#xff01; 一&#xff1a;首先到maven官网&#xff1a;http://maven.apache.org/&#xff0c;然后选择相应的版本下载&#xff0c;我这里下载的是maven…

学习笔记18-C语言-文件

文件的分类&#xff1a; 文本文件&#xff1a; 存储的是ASCII码值的二进制 二进制文件&#xff1a; 存储的是数据的补码文件IO&#xff1a; FILE *fopen(const char *path, const char *mode); 功能&#xff1a;打开或者创建文件 path&#xff1a;文件的路径 mode&#x…

使用INNER JOIN ON 多表关联查询,获取指定用户下指定权限的资源SQL:

摘要&#xff1a;最近在看一个开源框架&#xff0c;其中用户&#xff0c;角色&#xff0c;资源&#xff0c;这块我感觉比较重要&#xff0c;所以就自己也模仿着写了下&#xff0c;其中在获取指定用户下的权限资源的时候遇到问题了&#xff0c;开始时&#xff0c;我首先想到的方…

Maven学习记录之maven基本操作命令,maven本地工厂的创建,maven骨架的生成,以及在eclipse中创建maven工程:...

摘要&#xff1a;今天又学习了一下maven&#xff0c;之前是下载并安装和配置好了maven的环境&#xff0c;今天主要学习的内容包括&#xff1a;maven本地工厂的创建&#xff0c;maven骨架的生成命令&#xff0c;maven在dos下创建maven工程&#xff0c;以及在eclipse中创建mavne工…

Oracle中通过游标执行带参数的存储过程实现解析CLOB字段内的xml字符串:

摘要&#xff1a;近来之前的项目数据出现了问题&#xff0c;原因是由于之前在设计数据库的时候把时间字段设置成了字符串格式&#xff0c;所以给后期的数据操作带来了很大的麻烦&#xff0c;这里提醒一下各位程序猿&#xff0c;以后在开发项目的时候时间字段一定要是时间字段&a…

Eclipse中使用Checkstyle,checkstyle插件检查java代码的自定义配置文件:

摘要&#xff1a;近来项目组在搞代码检查&#xff0c;所以领导让把checkstyle这个插件搞明白&#xff0c;现在我把我们写的自定义的checkstyle.xml文件记录一下&#xff0c;以便大家可以一起使用&#xff1a; 一&#xff1a;要使用checkstyle插件在eclipse中检查java代码&…

Linux 下安装 jdk-7u75-linux-x64.gz,jdk1.7.0_75,jdk1.7步骤:

摘要&#xff1a;近来又用到了Linux系统&#xff0c;所以就又新装了一个虚拟机和CentOS 6.4来用&#xff0c;搞开发的程序猿们可能都知道&#xff0c;在现在的很多企业中&#xff0c;生产环境大多都是Linux服务器&#xff0c;并且用的比较多的大都是CentOS&#xff0c;Red hat系…

Win7+VMware10.0+CentOS 6.4+Tomcat,Win7访问不了CentOS6.4上的Tomcat

摘要&#xff1a;今天在linux下安装Tomcat后&#xff0c;在虚拟机本地通过:http://localhost:8080/可以访问安装好的Tomcat服务器&#xff0c;但是在本机就不能访问&#xff0c;前提是在本机下可以ping的通虚拟机的IP地址的&#xff0c;最后经过Google&#xff0c;发现说可能是…

Linux下配置OpenLDAP服务记录

摘要&#xff1a;最近部门需要整合所有的系统&#xff0c;所以领导说要通过OpenLdap数据库来实现对所有系统的统一管理&#xff0c;所以需要在服务器上配置一下LDAP服务&#xff0c;我们这里选择的是OpenLdap服务&#xff0c;我在网上搜索了很多&#xff0c;开始都没有配置成功…

Linux下配置CollabNet Subversion Edge

摘要&#xff1a;最近一直都在搞一下管理员的工作&#xff0c;今天又搞了svn的管理工具CollabNetSubversionEdge&#xff0c;网上也有很多例子&#xff0c;但是很多都是可以访问到web界面&#xff0c;但是不能启动版本库的服务&#xff0c;所以我经过多次尝试&#xff0c;终于解…

养成让自己进步的10个习惯

养成让自己进步的10个习惯 1.永远不说不可能。"办法总比问题多" 2.凡事第一反应找方法&#xff0c;不是找借口。"不要推卸责任" 3.养成记录习惯&#xff0c;不太依赖脑袋。"好记性不如烂笔头" 4.每天出门照镜子&#xff0c;给自己自信的微笑。&…

Oracle存储过程中使用游标来批量解析CLOB字段里面的xml字符串:

摘要&#xff1a;之前在项目中使用到了Oracle数据库中通过触发器去调用存储过程执行数据解析并Update到对应的数据表中&#xff0c;但是&#xff0c;经过一段时间的测试使用发现&#xff0c;如果job那天停掉了&#xff0c;然后你再重新新建job的话&#xff0c;这时候可能会有很…

Maven配置nexus

摘要&#xff1a;近来一直在搭建maven结构的开发框架&#xff0c;其中这个过程中用到了nexus私服&#xff0c;这里我把我经过查询总结的最终的方式记录一下&#xff0c;以便后面忘记了&#xff1a; 一&#xff1a;nexus私服的安装(略) 二&#xff1a;仓库的讲解如下图: 1、ho…

Maven项目发布的配置

摘要&#xff1a;要想发布maven结构的项目到nexus私服上&#xff0c;可以通过两种方式来&#xff0c;一种是在项目的pom.xml文件里面配置&#xff0c;另一种是通过命令的方式发布到nexus私服上&#xff0c;但是这种方式的前提也得在settings.xml文件配置用户: 一&#xff1a;M…