歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> 嵌入式開發第八日(linux內存起源,內存的分布)

嵌入式開發第八日(linux內存起源,內存的分布)

日期:2017/3/3 11:24:19   编辑:Linux技術

內存的起源:

其實我們談到的內存以及內存地址,指的都是“虛擬內存”和“虛擬內存地址”,他是linux操作系統為了更好的使用內存,而將實際物理內存進行映射,對應用程序屏蔽了物理細節,有利於簡化程序的編寫和系統的管理。假設正在使用的物理內存只有1GB,而當前系統運行了三個程序,那麼系統會將PM中的某些物理內存,映射為三個大小均為4GB的虛擬內存,讓每個進程都以為自己有了完整的空間,這樣極大地方便了應用層的數據和代碼的組織。

——Linux環境編程圖文指南

內存布局:

4GB的內存分布

-----------------------------------------------------內核 (kernel) 占1GB

------------------------------------------------------ <-- 0xc000 0000

棧(stack) “先進後出”原則

存放局部變量(包含形參)

最大限度為8MB 超過就會棧溢出

他會在運行時不斷的變化

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

||

V-------------------------------------

標准I/0 緩沖區

-------------------------------------

^

||

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

這是一個自由內存。

與棧最大的區別就是不限制大小

他會在運行時不斷的變化

堆(Heap)

------------------------------------------------------

數據段

.bss

存放未初始化的靜態變量(將被初始為0)

.data

存放已經初始化的靜態變量

.rodata

存放常量 如字符串啊 ,字符常量啊。

-------------------------------------------------------

代碼段

.text

用戶編寫的代碼

.init

可執行程序的“初始化”代碼

----------------------------------------------------

<-- 0x0804 8000

不可訪問

------------------------------------------------------ <-- 0x0000 0000

局部變量/全局變量

局部變量是指{}中,未用static 修飾的變量;

局部變量如果沒有初始化,則值為隨機值

只在對應的{}范圍有效

全局變量

在{}之外,沒有被{}圈住,靜態存儲

如果全局變量沒有被初始化,gcc工具默認初始化為0

一般定義在代碼最開始

static 靜態變量 靜態存儲

static 數據類型 變量名

這變量的值只會初始化一次,此後用的值都是上一次保存的值

存在數據段中

靜態局部變量

{}范圍內有效

靜態全局變量

本文件內有效

ps:盡量少用靜態變量, 靜態變量在程序退出之前都不會釋放內存,會無條件的一直占用。

如果要用 盡量使用同步互斥來保護他們。

register 只能作用於{}對應的代碼塊,動態存儲

1、直接操作寄存器,效率高

2、linux裡面有寄存器變量的上限,如果超出這個上限,是申請不到的

extern 在本文件中調用其它文件中的全局變量或者函數

堆操作函數(malloc calloc realloc free)

#include <stdlib.h>void *malloc(size_t size);

void free(void *ptr);

void *calloc(size_t nmemb, size_t size);

void *realloc(void *ptr, size_t size);

malloc

void *malloc(size_t size);

申請一段連續的堆裡面的空間

返回值是個指針,所以是指針函數

返回值為NULL,表示申請失敗

申請得到的堆空間,初始值為隨機數

size_t size:申請的空間大小 size_t int

void *p = malloc(sizeof(int)) //最為常用

==>int *p = (int *)malloc(sizeof(int));

申請100個int

int *p = (int *)malloc(sizeof(int)*100);

可以利用指針+1特性,逐個找個各個單元,對每一個單元做讀寫

*(p+i) 切換p++(釋放時會找不到原先開辟的起始地址)

void *calloc(size_t nmemb, size_t size);

nmemb 是指由多少個元素,size 每一個元素占多大空間

申請的內存將被初始化為零,

void *realloc(void *ptr,size_t size);

在現在其地址的基礎上,更改申請空間的大小

void free(void *ptr);

釋放堆空間,ptr申請的起始地址,但是裡面的內容可能還可能存在,也可以繼續訪問,但是是非法。

free釋放內存後,指針將會變成野指針~~

======================================

const char *str 表示*str只讀的

==char const *str

不能去修改*str裡面的數據

char * const str

str 在定義的時候初始化,此後不能再被賦值,保護的是str本身。

1、指出以下代碼第二次輸出的結果,解釋原因。

void other(void)

int main(void)

{

extern int a;

int b=0;

static int c;

a+=3;

func();

b+=3;

func();

}

int a = 5;

void fun(void)

{

int b=3;

static int c=2;

a+=5;

b+=5;

c+=5;

printf("%d,%d,%d",a,b,c);

c=b;

}

2、說出C程序中所有不同的存儲類型變量在內存中的詳細分布情況

3、在堆中開辟一段內存,分別存儲不同的值,再進行加法運算

4、復習程序內存布局

Copyright © Linux教程網 All Rights Reserved