欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

動態(tài)內(nèi)存分配/管理-創(chuàng)新互聯(lián)

目錄

成都創(chuàng)新互聯(lián)公司基于成都重慶香港及美國等地區(qū)分布式IDC機房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)綿陽服務(wù)器托管報價,主機托管價格性價比高,為金融證券行業(yè)服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨享,G口帶寬及機柜租用的專業(yè)成都idc公司。

1、為什么要有動態(tài)內(nèi)存分配

2、動態(tài)內(nèi)存函數(shù)介紹

1、malloc

2、free

3、calloc

?編輯

4、realloc

3、動態(tài)內(nèi)存常見的錯誤

4、動態(tài)內(nèi)存開辟相關(guān)好題

5、c/c++程序內(nèi)存開辟示意圖


int a,? int arr[10]? 是固定地向內(nèi)存申請連續(xù)的一塊空間,但不能變長或變短隨時調(diào)整。

在我們之前寫的靜態(tài)版通訊錄中,我們創(chuàng)建了一個peopleinfo類型的數(shù)組date[100]用來存放100個人的個人信息,但是當(dāng)我們的人員信息較小時,100個結(jié)構(gòu)體顯得有些浪費,而當(dāng)我們所需存放的信息超過100時又不夠用,隨之我們就得修改這個數(shù)字,但是學(xué)了動態(tài)內(nèi)存管理之后,我們可以動態(tài)地分配內(nèi)存空間變大或變小,從而有效利用空間。

1、為什么要有動態(tài)內(nèi)存分配

int val = 20;//在棧空間上開辟四個字節(jié)
char arr[10] = {0};//在棧空間上開辟10個字節(jié)的連續(xù)空間
但是上述的開辟空間的方式有兩個特點:
1. 空間開辟大小是固定的。
2. 數(shù)組在申明的時候,必須指定數(shù)組的長度,它所需要的內(nèi)存在編譯時分配。
但是對于空間的需求,不僅僅是上述的情況。有時候我們需要的空間大小在程序運行的時候才能知道,
那數(shù)組的編譯時開辟空間的方式就不能滿足了。
這時候就只能使用動態(tài)內(nèi)存開辟了。

2、動態(tài)內(nèi)存函數(shù)介紹 1、malloc

#include

這個函數(shù)向內(nèi)存申請一塊連續(xù)可用的空間,并返回指向這塊空間的指針。
如果開辟成功,則返回一個指向開辟好空間的指針。
如果開辟失敗,則返回一個NULL指針,因此malloc的返回值一定要做檢查。
返回值的類型是 void* ,所以malloc函數(shù)并不知道開辟空間的類型,具體在使用的時候使用者自己
來決定。
如果參數(shù) size 為0,malloc的行為是標(biāo)準(zhǔn)是未定義的,取決于編譯器。

先在堆區(qū)上動態(tài)申請一定空間,使用后應(yīng)該還給操作系統(tǒng),如果不主動還,程序結(jié)束后會自動還,但是如果程序一直不結(jié)束,就一直“占著不用”,就會造成空間的浪費。

2、free

用來釋放、歸還申請的內(nèi)存

int main()
{
	//申請40個字節(jié),用來存放10個整型
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	//存放  1--10
	int i = 0;
	for (i = 0; i< 10; i++)
	{
		*(p + i) = i + 1;
	}
	for (i = 0; i< 10; i++)
	{
		printf("%d ", *(p+i));
	}
	//free釋放申請的內(nèi)存
	free(p);

	return 0;
}

用malloc申請后,內(nèi)存中為隨機值,使用時可給它們賦值,當(dāng)free后,又變?yōu)殡S機值。

仔細(xì)觀察,我們可以發(fā)現(xiàn),雖然這塊空間的值發(fā)生了變化,但是指針p指向的地址free前后沒有變化。因此,當(dāng)我們free還給操作系統(tǒng)后,p仍指向這塊空間。此時*p就會導(dǎo)致非法訪問,因此我們需要將p制為NULL,避免非法訪問。

free(p);
	p = NULL;

總結(jié):malloc申請空間后不會初始化,使用前要判斷是否成功申請(是否返回NULL),使用后要free還給操作系統(tǒng),然后將用于接收這塊內(nèi)存空間的指針p置為NULL。

申請失敗時返回NULL,并打印錯誤原因(沒有足夠空間)。

void? free(void * ptr)

free函數(shù)用來釋放動態(tài)開辟的內(nèi)存。
如果參數(shù) ptr 指向的空間不是動態(tài)開辟的,那free函數(shù)的行為是未定義的。
如果參數(shù) ptr 是NULL指針,則函數(shù)什么事都不做。

3、calloc

由上圖我們可以知道,malloc不會初始化,calloc會將每個元素先初始化為0,可以按需用。由于calloc需要初始化,效率比malloc稍低,此外沒有其它區(qū)別,都需要進行相關(guān)步驟。

4、realloc

int main()
{
	int* p = (int*)malloc(5 * sizeof(int));
	if (NULL == p)
	{
		perror("malloc");
		return 1;
	}//使用
	int i = 0;
	for (i = 0; i< 5; i++)
	{
		p[i] = 1;
	}//空間不夠,增加5個整型的空間
	//此時不能用p接收
	int* ptr = (int*)realloc(p, 10 * sizeof(int));
	//先用ptr接收,再賦給p,防止返回NULL,p找不到原來的數(shù)據(jù)
	if (ptr != NULL)
	{
		p = ptr;
        ptr = NULL;//釋放但不置空,需手動置空
	}
	//繼續(xù)使用
	for (i = 0; i< 10; i++)
	{
		printf("%d ", p[i]);
	}//realloc會把舊的空間釋放,不用自己釋放
	free(p);
	p = NULL;
}

3、動態(tài)內(nèi)存常見的錯誤

1、對NULL解引用(未判斷是否為空)

2、非法訪問內(nèi)存,越界訪問(解引用野指針)

3、對非動態(tài)開辟內(nèi)存的空間用free釋放

void test()
{
int a = 10;
int *p = &a;
free(p);//ok?
}

對棧區(qū)的空間進行釋放(x)

4、使用free釋放一塊動態(tài)開辟內(nèi)存的一部分

void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向動態(tài)內(nèi)存的起始位置
p=NULL;
}

5、對同一塊內(nèi)存多次釋放

void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重復(fù)釋放
}

free一個NULL空指針時,什么事都不會發(fā)生。

malloc等函數(shù)是申請一塊空間,獲得使用它的權(quán)限,free釋放后,將權(quán)限還給操作系統(tǒng),如果再訪問或是釋放,就是非法訪問。
6、動態(tài)開辟的內(nèi)存忘記釋放(內(nèi)存泄漏)

malloc和free要成對出現(xiàn),防止出現(xiàn)內(nèi)存泄漏

int* test()
//函數(shù)內(nèi)部進行了malloc操作,返回了malloc開辟的空間的起始地址
//誰接收了  要記得釋放和置空
{
	int* p = (int*)malloc(100);
	if (NULL == p)
	{
		return 1;
	}
	return p;
}
int main()
{
	int* ptr = test();
	free(ptr);
	ptr = NULL;
}
4、動態(tài)內(nèi)存開辟相關(guān)好題
void GetMemory(char *p)
{
    p = (char *)malloc(100);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str, "hello world");
    printf(str);
}
int main()
{
    Test();
}

這里GetMemory函數(shù)是值傳遞,且沒有返回值,對str無影響。因此str還是指向NULL,即0地址處,然后調(diào)用strcpy需訪問0地址處內(nèi)容,導(dǎo)致非法訪問。

同時,上面用malloc申請了一塊空間,但是函數(shù)內(nèi)沒有釋放,函數(shù)銷毀后,p也銷毀,這塊空間就會內(nèi)存泄漏。記得malloc要與free搭配使用。

修改后,可傳入&str,用char**p接收,*P=(char*)malloc(100),使p指向開辟的100byte,進而存放拷貝的內(nèi)容,打印后free(str) str=NULL

或者將p(char*)直接返回,用str接收,因為沒有free,所以malloc(100)仍然存在,進而可以strcpy,如果此時不是malloc申請,而是利用數(shù)組,函數(shù)銷毀后,數(shù)組的空間也會釋放,如果再進行打印就不行了。(如下圖)這類問題簡稱為 返回棧空間地址的問題

可以在p前面加上static使其變?yōu)殪o態(tài)區(qū)變量,函數(shù)銷毀后它不會銷毀,或者去掉[],p變?yōu)閏har*類型,即從數(shù)組變?yōu)槌A孔址A孔址彩窃陟o態(tài)區(qū),也就是把在棧區(qū)存儲的數(shù)據(jù)放入靜態(tài)區(qū)中存儲,從而避免了返回棧空間地址的問題。

printf(str)括號內(nèi)直接加str是可以的,str是一個地址,例如printf(“hehe”),括號內(nèi)有引號+字符串,也就是首字符的地址,相當(dāng)于括號內(nèi)直接加一個地址,最終結(jié)果都是打印字符串。

void GetMemory(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(&str, 100);
    strcpy(str, "hello");
    printf(str);
}
int main()
{
    Test();
}

這段代碼的整體思路沒有問題,但是會導(dǎo)致內(nèi)存泄漏,? malloc等函數(shù)需要與free共同使用

void Test(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, "hello");
    free(str);
}
    if(str != NULL)
{
    strcpy(str, "world");
    printf(str);
}

free(str)后已經(jīng)沒有權(quán)限訪問了,但后面又調(diào)用strcpy訪問空間,導(dǎo)致非法訪問

開辟--釋放--置空

習(xí)題來自《高質(zhì)量C/C++編程》

5、c/c++程序內(nèi)存開辟示意圖

1. 棧區(qū)(stack):在執(zhí)行函數(shù)時,函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)
束時這些存儲單元自動被釋放。棧內(nèi)存分配運算內(nèi)置于處理器的指令集中,效率很高,但是
分配的內(nèi)存容量有限。 棧區(qū)主要存放運行函數(shù)而分配的局部變量、函數(shù)參數(shù)、返回數(shù)據(jù)、返
回地址等。
2. 堆區(qū)(heap):一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收 。分
配方式類似于鏈表。
3. 數(shù)據(jù)段(靜態(tài)區(qū))(static)存放全局變量、靜態(tài)數(shù)據(jù)。程序結(jié)束后由系統(tǒng)釋放。
4. 代碼段:存放函數(shù)體(類成員函數(shù)和全局函數(shù))的二進制代碼,只讀常量(不能被修改),字符串常量。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站名稱:動態(tài)內(nèi)存分配/管理-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://chinadenli.net/article42/gedec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設(shè)全網(wǎng)營銷推廣自適應(yīng)網(wǎng)站靜態(tài)網(wǎng)站響應(yīng)式網(wǎng)站品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁設(shè)計公司