回顾:
brk/sbrk
int brk(void *p); 改变绝对位置。
void *sbrk(int); 相对改变位置。
维护一个位置。brk/sbrk改变这个位置
补充:全新的类型
c的基本类型就:整数(1,2,4),小数(4,8)
所有全新类型都是使用typedef重新定义,新的类型的c的原型
类型重定义的好处:
1 维护方便
2 移植
3 容易理解
一 映射虚拟内存
没有任何额外维护数据的内存分配
mmap(分配)/unmap(释放)
1 函数说明
void *mmap(
void *addr, // 指定映射的虚拟地址 0由系统指定位置
size_t length, // 映射空间大小 pagesize倍数
int prot, // 映射权限 PROT_NONE PROT_READ PROT_WRITE PROT_EXEC
int flags, //映射方式 内存映射:匿名映射。 文件映射:映射到某个文件 只有文件映射最后两个参数才有效
int fd, //文件描述符号
off_t offset); // 文件中的映射开始位置 (必须是pagesize的倍数)
MAP_ANONYMOUS
MAP_SHARD MAP_PRIVATE(二选一)
2 案例
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
int *p = mmap(
NULL,
getpagesize(),
PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_SHARED,
0,0);
*p = 20;
*(p+1) = 30;
*(p+2) = 30;
printf("%d\n",p[2]);
munmap(p, 4096);
return 0;
}
3 总结
选择什么样的内存管理办法?
智能指针(指针池)
STL
new
malloc(小而多数据)
brk/sbrk(同类型大块数据,动态移动指针)
mmap/munmap(控制内存访问/使用文件映射/控制内存共享)
4 应用
二 编译工具与动态库
1、gcc
-o 输出文件名
-O -O0 -O1 -O2 -O3 编译优化
-g -g0 -g1 -g2 -g3 产生调试信息
-Wall 显示所有警告 -Werror 把警告当错误
-w 关闭警告
-c 只编译不链接
-E 预编译
-S 汇编
-D 在命令行定义宏
在代码中定义宏,在命令行定义宏
-x 指定编译语言类型
-std = C89
-std = C99
编译过程: -E -c -S 自动调用连接器
连接器 ld
补充:.c .cpp .h .hpp .o .a .so .i 预编译文件 .s 汇编文件
三、静态库的编译
1、编译过程(*.a achieve)
编译成目标文件
-static
gcc -c -static 代码文件.c
归档成静态库
ar 工具 -r -t 静态库文件 被归档文件
nm工具(查看函数符号表) 静态库或者动态库或者目标文件或者执行文件
gcc 代码 静态库
使用静态库完成如下程序:
输入菱形半径,打印菱形 输入整数封装成IOTool 菱形的打印封装成Graphics
#include <stdio.h>
int inputInt(const char * info)
{
int r;
printf("%s", info);
scanf("%d", &r);
return r;
}
#include <stdio.h>
void diamond(int r)
{
int x, y;
for(y = 0; y <= 2*r; y++)
{
for(x = 0; x <= 2*r; x++)
{
if(y == x + r || y == x + r || y == -x + r || y == -x + 3*r)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
四、动态库的编译