C++嵌入式学习第十天

malloc内存管理机制:
当首次使用malloc申请内存时,malloc会向操作系统申请内存,操作系统会直接给malloc分配33页(1页=4096字节)内存交给malloc管理。但是不意味着你可以越界访问,因为malloc可能会把使用权分配给“其他人”,这就会导致脏数据。

每个内存块之间都会有一些空隙(4~12字节),这些空隙一些是为了内存数据对齐,其中一定会有4个字节是用于记录malloc维护信息,这些维护信息决定了下次malloc分配内存的位置,以及借助这个维护信息计算出每个内存块的大小,当这些信息被破坏时,会影响下一次malloc和free函数的调用。

使用堆内存要注意的问题:
内存泄漏:
内存无法再次使用,也无法被释放,而再次使用时只能重新申请,然后重复以上操作,最后导致日积月累后系统中可以使用的内存越来越少。
注意:程序一旦结束后,属于该程序的所有资源都会被操作系统回收。

    如何尽量避免内存泄漏:
        谁申请谁释放, 谁知道该释放谁释放
    
    如何判断定位内存泄漏:(自己搜索一下)
        1、查看内存的使用情况 ps -aux
        2、使用代码分析工具来检查malloc和free的调用情况
        3、包装malloc和free函数,记录申请、释放内存信息到日志中。

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

内存清理函数:
#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:想要设置的字符的ASCII码值
n:要设置的内存块的字节数
返回值:返回设置成功后的内存块的首地址

堆内存来定义二维数组:
指针数组:定义nm的二维数组
类型
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之间的所有素数,结果要存储在堆内存中,不能浪费内存。
    1、计算出个数,然后一下申请出来,再计算后存储
    2、一边算一边扩充

字符:char ch;
在计算机中字符是以整数形式存储在内存中,当需要时显示为字符时,会根据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] = {‘a’,‘b’,‘c’};
由char类型组成的数组,要为’\0’预留位置
使用的是栈内存,因此数据可以修改
字符串字面值:“Hello World”
“由双引号包含的若干个字符”,会在末尾隐藏一个\0
字符串字面值是以地址形式存在的,数据是存储在代码段,如果修改则会产生段错误
const char* p = “字符串字面值”;
sizeof(“strstr”); 结果= 字符个数+1
两个一模一样的字符串字面值在代码段中只存储一份

常用方式: 字符数组[] = "字符串字面值";
    会自动为'\0'预留位置
    注意:赋值完成后字符串就存在了两份,一份存储在代码段,一份存储在栈内存(可修改)

练习2:实现一个函数,判断字符串是否是回文串
练习3:实现一个函数,把由数字字符组成的字符串转换为整数
“1234” 1234
练习4:实现一个函数,把字符串逆序
练习5:实现一个抽奖功能,有十人的名单,随机顺序列出人名

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值