1.Unix/Linux的内存相关函数和调用关系
STL -> 内存自动分配和自动回收|
C++ -> new/delete运算符 new分配 delete回收
|
C -> malloc()分配 free()回收
|
Unix系统函数-> sbrk() brk() 都是既能分配和回收
|
Unix系统函数-> mmap()分配 munmap()回收
| Unix/Linux的用户层内存关系
------------------------------------------------
| 内核层(了解)
malloc() vmalloc()
|
get_free_page()
内存分配时候,函数图是 由上到下 小调用。
2.一个进程的内存空间包括以下
几个部分:
(1)代码区:程序的代码(函数)放入代码区,只读区
(2)全局区:存放全局变量和static变量,main函数执行之前 分配全局区
(3)BSS段:存放未初始化的全局变量,mian函数执行之前,清空BSS段(清0)
(4)栈区:非static的局部变量,包括函数的参数。栈区的内存 自动分配和自动回收。
(5)堆区:也叫自由区,malloc()、free()就是操作堆区内存,程序员完全掌控堆区内存的分配和回收
(6)只读常量区:常量和字符串的字面值(“ ”),只读区,有些资料没有分出只读常量区,而是统称为代码区。
从低到高:代码段——》数据段——》BSS——》堆——》栈
int i1 = 1;//全局
int i2 = 2;//全局
int i3;//BSS段
static int i4 = 4;//全局
const int i5 = 5;//只读常量区
void fa(int i6){//i6栈区,fa代码区
int i7;//栈区
static int i8 = 8;//全局区
const i9 = 9;//const局部变量也在栈区
int* pi = malloc(4);//堆
int* pi2 = (int*)12345;//有地址,但是没有映射
char* str = "abd";//只读常量区
char str2[] = "abc";//数组格式在栈区
printf("i6=%p\n",&i6);
printf("i7=%p\n",&i7);
printf("i8=%p\n",&i8);
printf("i9=%p\n",&i9);
printf("pi=%p\n",pi);
printf("str=%p\n",str);
printf("str2[]=%p\n",str2);
}
int main(){
printf("展示相应的地址:\n");
printf("i1=%p\n",&i1);
printf("i2=%p\n",&i2);
printf("i3=%p\n",&i3);
printf("i4=%p\n",&i4);
printf("i5=%p\n",&i5);
printf("fa=%p\n",fa);//函数名就是函数指针
fa(6);
printf("PID=%d\n",getpid());
return 0;
}
char* 用=赋值,char[]用strcpy赋值
int main()
{
char *s1 = "abc";//s1是地址,指向"abc"只读区
char s2[] = "abc";//s2是数组,在栈中分配空间,把“abc”值复制到栈区,指向栈区
char* s3 = s2;//s3指向栈,不是常指针
// strcpy(s1,"123");//错,s1指向只读区,不能修改,引发段错误
s1 = "123";//
strcpy(s2,"123");//对
// s2 = "123";//错,常指针不能改变指向(地址)
char* s4 = malloc(4);//s4指向了堆,不是常指针
char* s5 = malloc(4);//s4指向了堆,不是常指针
s4 = "abc";//s4 只读区
s4 = "cici";
strcpy(s5,"456");//改值的正确用法
printf("s1=%s,s2=%s,s3=%s,s4=%s,s5=%s\n",s1,s2,s3,s4,s5);
return 0;
}