欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言?動態(tài)內(nèi)存管理全面解析

 更新時間:2022年02月11日 10:01:15   作者:i跑跑  
動態(tài)內(nèi)存是相對靜態(tài)內(nèi)存而言的。所謂動態(tài)和靜態(tài)就是指內(nèi)存的分配方式。動態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存,本文帶你深入探究C語言中動態(tài)內(nèi)存的管理

1. 為什么存在動態(tài)內(nèi)存分配

*動態(tài)內(nèi)存開辟在堆區(qū)*

我們已經(jīng)掌握的開辟內(nèi)存方式是類型直接定義變量,開辟的內(nèi)存是固定的,像:

int a=20;  //在棧空間上開辟四個字節(jié)

還有數(shù)組,我們可以指定開辟空間的大小,像:

char arr[10] = {0};  ///在??臻g上開辟10個字節(jié)的連續(xù)空間

但在程序運行時,很多時候我們會遇到內(nèi)存不夠或者內(nèi)存過多引起的浪費問題,那么有沒有那種使用多少內(nèi)存開辟多少內(nèi)存的方法?這就是本篇文章要介紹的動態(tài)內(nèi)存。

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

2.1 malloc和free

malloc和free都聲明在 stdlib.h 頭文件中

void* malloc (size_t size);
//向內(nèi)存申請一塊連續(xù)可用的空間,并返回指向這塊空間的指針

如果開辟成功,則返回一個指向開辟好空間的指針。 如果開辟失敗,則返回一個NULL指針。 返回值的類型是 void* ,malloc函數(shù)并不知道開辟空間的類型,在使用的時候自己來決定。

void free (void* ptr);
//free函數(shù)用來釋放動態(tài)開辟的內(nèi)存

如果參數(shù) ptr 指向的空間不是動態(tài)開辟的,那free函數(shù)的行為是未定義的。

如果參數(shù) ptr 是NULL指針,則函數(shù)什么事都不做。

舉例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
	//開辟10個整型空間
	int* p = (int*)malloc(40);
	if (NULL==p)
	{
		printf("%s\n",strerror(errno));  //判斷開辟失敗的原因
		return 0;
	}
	//使用
 
	//釋放
	free(p);  //將空間還給系統(tǒng),但是里面的內(nèi)容沒有改變,還可以通過p來找到地址
	p = NULL;  //因此要將地址置為空指針
	return 0;
}

2.2 calloc 

void* calloc (size_t num, size_t size);
//num為元素個數(shù),size為每個元素的大小

注:與函數(shù) malloc 的區(qū)別只在于 calloc 會在返回地址之前把申請的空間的每個字節(jié)初始化為全0

當(dāng)用calloc來開辟10個整型空間時

int* p = (int*)calloc(10,sizeof(int));

2.3 realloc

void* realloc (void* ptr, size_t size);
//ptr 是要調(diào)整的內(nèi)存地址     size 調(diào)整之后新大小
//返回值為調(diào)整之后的內(nèi)存起始位置

realloc在調(diào)整內(nèi)存空間的是存在兩種情況:

1.當(dāng)原地址后有足夠的空間時,可以接著原地址連續(xù)開辟空間,最后返回起始地址。

2.當(dāng)原地址后空間不足以開辟我們所需要的空間時,那么realloc會自動尋找一塊足以存放我們需要的的空間,并將原地址的內(nèi)容復(fù)制到新空間中,釋放掉原地址中的內(nèi)容,返回開辟出空間的初始地址。

我們可以先判斷是否開辟成功,再將地址賦予p

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

3.1 對NULL指針的解引用操作

開辟動態(tài)內(nèi)存時,一定要注意對返回空指針的函數(shù)要進(jìn)行判斷,防止對空指針進(jìn)行解引用,以免程序出現(xiàn)問題。

3.2 對動態(tài)開辟空間的越界訪問

 int *p = (int *)malloc(10*sizeof(int));   //開辟內(nèi)存
 
 if(NULL == p)    //判斷是否開辟成功
 {
 exit(EXIT_FAILURE);
 }
 
 int i=0;
 for(i=0; i<=10; i++)
 {
 *(p+i) = i;//當(dāng)i是10的時候越界訪問
 }
 free(p);

這塊可以像理解數(shù)組一樣,不能訪問下標(biāo)為10的地址,會造成越界訪問。

3.3 對非動態(tài)開辟內(nèi)存使用free釋放

void test()
{
	int a = 10;
	int *p = &a;
	free(p);
}
 
 
int main()
{
	test();
	return 0;
}

不是動態(tài)內(nèi)存開辟的空間內(nèi)存不在堆區(qū),沒必要用free釋放,在棧區(qū)開辟的空間在出了作用域后會自動還給系統(tǒng),沒有必要,也不允許用free進(jìn)行釋放。

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

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

 不支持釋放一部分內(nèi)存,這樣的寫法不支持不可取。只能從動態(tài)內(nèi)存開辟的起始位置來進(jìn)行釋放。

3.5 對同一塊動態(tài)內(nèi)存多次釋放

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

重復(fù)釋放也會報錯

當(dāng)p第一次釋放后,將p=NULL,再次釋放的話就不會有問題;寫代碼是要避免重復(fù)釋放的情況,同時要記住每次釋放完之后都要將地址置為空指針。

若忘記釋放開辟的空間,就會造成內(nèi)存泄漏的問題(在釋放該段內(nèi)存之前就失去了對該段內(nèi)存的控制,從而造成了內(nèi)存的浪費)

到此這篇關(guān)于C語言 動態(tài)內(nèi)存管理深入理解的文章就介紹到這了,更多相關(guān)C語言 動態(tài)內(nèi)存管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt編寫地圖實現(xiàn)實時動態(tài)軌跡效果

    Qt編寫地圖實現(xiàn)實時動態(tài)軌跡效果

    實時動態(tài)軌跡主要是需要在地圖上動態(tài)顯示GPS的運動軌跡,也是編寫地圖時一個重要的功能。本文將利用Qt實現(xiàn)這一功能,需要的可以參考一下
    2022-02-02
  • C++學(xué)校運動會管理系統(tǒng)的實現(xiàn)

    C++學(xué)校運動會管理系統(tǒng)的實現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C++如何實現(xiàn)學(xué)校運動會管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • C語言獲取文件大小的兩種方式

    C語言獲取文件大小的兩種方式

    因為音視頻開發(fā)的需要,經(jīng)常會寫一些文件輸入輸出的測試程序,常常用到獲取文件大小的函數(shù),本篇文章就記錄一下常用的兩種獲取文件大小的方式,希望對大家有所幫助
    2023-11-11
  • C++中的vector容器對象學(xué)習(xí)筆記

    C++中的vector容器對象學(xué)習(xí)筆記

    這篇文章主要介紹了C++中的vector容器對象學(xué)習(xí)筆記,其中文章最后標(biāo)紅的resize與reserve方法的差別特別需要注意,需要的朋友可以參考下
    2016-05-05
  • C++常用字符串函數(shù)大全(2)

    C++常用字符串函數(shù)大全(2)

    這篇文章主要給大家分享的是C++常用字符串函數(shù)的大全,cstring.h庫即C語言中的string.h庫,它是C語言中為字符串提供的標(biāo)準(zhǔn)庫。C++對此進(jìn)行了兼容,所以我們在C++當(dāng)中一樣可以使用,下面文章的詳細(xì)內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • 貪心算法的C語言實現(xiàn)與運用詳解

    貪心算法的C語言實現(xiàn)與運用詳解

    這篇文章主要介紹了貪心算法的C語言實現(xiàn)與運用詳解,運用么,就是文中所附的ACM練習(xí)題,哈哈:D需要的朋友可以參考下
    2015-08-08
  • C經(jīng)典算法之二分查找法

    C經(jīng)典算法之二分查找法

    這篇文章主要介紹了C經(jīng)典算法之二分查找法的相關(guān)資料,這里提供兩種方法幫助大家實現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-10-10
  • C++ Vector用法深入剖析

    C++ Vector用法深入剖析

    C++ Vector應(yīng)用方式是比較特殊的,我們將會在這篇文章中針對于它的應(yīng)用方式進(jìn)行一個詳細(xì)的介紹,希望大家能充分掌握這一應(yīng)用技巧
    2014-08-08
  • 關(guān)于C++中push_back()函數(shù)的用法及代碼實例

    關(guān)于C++中push_back()函數(shù)的用法及代碼實例

    push_back是vector的一個方法,表示將一個元素存儲到容器的末尾,下面這篇文章主要給大家介紹了關(guān)于C++中push_back()函數(shù)用法的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • C語言中的運算符優(yōu)先級和結(jié)合性一覽表

    C語言中的運算符優(yōu)先級和結(jié)合性一覽表

    這篇文章主要介紹了C語言中的運算符優(yōu)先級和結(jié)合性一覽表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論