大疆嵌入式:
1、如何测试malloc的溢出问题
没有成对使用malloc和free会导致内存溢出;通过测试程序查看内存占用:
ps aux | grep a.out | grep -v grep
测试一:分配内存,不使用内存,也不释放内存。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main() {
int i = 0 ;
for(i = 0 ;i >=0 ; i++){
void *p = malloc(100000000) ;
printf("malloc %d*100000000\n", i);
//memset(p,'a',100000000) ;
//free(p) ;
sleep(1) ;
}
return 0;
}
虚拟内存使用一直在增长,但内存利用率%MEM和占用的固定内存量RSS都没变。
测试二:不断分配内存,使用内存,不释放内存
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main() {
int i = 0 ;
for(i = 0 ;i >=0 ; i++){
void *p = malloc(100000000) ;
printf("malloc %d*100000000\n", i);
memset(p,'a',100000000) ;
//free(p) ;
sleep(1) ;
}
return 0;
}
测试三:分配内存,使用内存,释放内存
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main() {
int i = 0 ;
for(i = 0 ;i >=0 ; i++){
void *p = malloc(100000000) ;
printf("malloc %d*100000000\n", i);
memset(p,'a',100000000) ;
//free(p) ;
sleep(1) ;
}
return 0;
}
结论:%MEM VSZ RSS 三个量都比较稳定
2、IIC SPI介绍,另外姿态解算部分,互补滤波如何处理的。
IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的一种简单、双向、二线制、同步串行总线,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。这种方式简化了信号传输总线接口。 I2C串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
SPI是串行外设接口(Serial Peripheral Interface)的缩写,顾名思义就是串行外围设备接口。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议。SPI数据传输速度总体来说比I2C总线要快,速度可达到几Mbps。
姿态解算互补滤波算法是一种常用的姿态解算方法,它可以通过融合加速度计和陀螺仪的数据,实现对物体的姿态角度的估计。该算法的主要思想是将加速度计和陀螺仪的数据进行互补滤波,从而得.到更加准确的姿态角度估计。
由于加速度计存在噪声和漂移等问题,单独使用加速度计进行姿态解算会存在误差。而陀螺仪可以测量物体的角速度,从而得到物体的角度变化率,但是由于陀螺仪存在累积误差,单独使用陀螺仪进行姿态解算也会存在误差。因此,姿态解算互补滤波算法将加速度计和陀螺仪的数据进行融合,从而得到更加准确的姿态角度估计。具体来说,该算法将加速度计和陀螺仪的数据分别进行滤波处理,然后将两者的结果进行加权平均,得到最终的姿态角度估计。
3、STL库的内存配置?二级内存配置,为啥是二级内存配置?为啥是128bytes?
空间配置器是操作系统开辟的一大段内存空间。STL需要扩容申请内存时,就从空间配置器中申请,不需要再经过操作系统。并且,它还能回收释放的空间,供下一次使用。一个进程中有一个空间配置器,进程中所有容器需要的空间都到对应空间配置器申请。进程终止,对应空间配置器空间释放。
一级空间配置器是用来处理大块内存,二级空间配置器处理小块内存。
一级空间配置器原理很简单,直接是对malloc和free进行了封装,并且增加了C++中的申请空间失败抛异常机制。
主要的作用是:向操作系统申请内存,申请失败会抛异常。
为什么不直接用C++的new和delete,因为这里并不需要调用构造函数和析构函数。
二级空间配置器专门负责处理小于128字节的小块内存。
内存碎片:
外碎片问题:
由于频繁申请小块内存,导致被申请的内存块不连续,如果下一次需要申请一大块内存,内存空间够,但是由于不连续,导致申请不出来。
内核针对大量申请在堆上小块内存导致碎片化的问题,是用来slab分配器来解决。结构类似二级空间配置器的哈希结构
内碎片问题:
内碎片问题:给的内存数比实际要的内存数多,导致空间浪费。二级配置器切割内存块向上对齐8的整数倍,就造成了内碎片问题
4、struct{char,double,int} 在64位占多少字节
64位操作系统,不同类型变量对应的字节数为:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double:
8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
64位系统在内存管理方面遵循8字节对齐,原则:在8字节对齐的情况下,按8个字节为单位分配存储空间,如果不足,会自动补充,本次分配不足以存放下面的变量时,会重新分配空间。
structA{
unsigned int a; //对于开始连续的第一个8字节内存,a占4字节
char b[2]; //b[]占1*2字节,在a后的连续2字节内存放,还剩2个字节,
double c; //c占8字节,第一个8字节还剩2字节不足以存放c,自动补充该2字节。并同时开辟第二个8字节内存存放c
short d;
//d占2字节,开辟第三个8字节,存放d。剩余的6个字节补齐。故总共开辟了8*3=24字节存放该数据结构
}