<del id="d4fwx"><form id="d4fwx"></form></del>
      <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

            <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
          • 動態(tài)內(nèi)存分配/管理-創(chuàng)新互聯(lián)

            目錄

            成都創(chuàng)新互聯(lián)公司基于成都重慶香港及美國等地區(qū)分布式IDC機房數(shù)據(jù)中心構建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)綿陽服務器托管報價,主機托管價格性價比高,為金融證券行業(yè)服務器托管,ai人工智能服務器托管提供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)存開辟相關好題

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


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

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

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

            int val = 20;//在??臻g上開辟四個字節(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的行為是標準是未定義的,取決于編譯器。

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

            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)存中為隨機值,使用時可給它們賦值,當free后,又變?yōu)殡S機值。

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

            free(p);
            	p = NULL;

            總結: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ū)別,都需要進行相關步驟。

            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);//重復釋放
            }

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

            malloc等函數(shù)是申請一塊空間,獲得使用它的權限,free釋放后,將權限還給操作系統(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)存開辟相關好題
            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)容,導致非法訪問。

            同時,上面用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孔址?,常量字符串也是在靜態(tài)區(qū),也就是把在棧區(qū)存儲的數(shù)據(jù)放入靜態(tài)區(qū)中存儲,從而避免了返回??臻g地址的問題。

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

            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();
            }

            這段代碼的整體思路沒有問題,但是會導致內(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)沒有權限訪問了,但后面又調(diào)用strcpy訪問空間,導致非法訪問

            開辟--釋放--置空

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

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

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

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

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

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

            廣告

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

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

              <del id="d4fwx"><form id="d4fwx"></form></del>
              <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

                    <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
                  • 天天操天天射天天好逼网 | 看永久免费黄色视频 | 国产三级国产精品 | H无码里番肉片在线播放 | 男人天堂官网 |