国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一文帶你了解動態(tài)內(nèi)存管理

這篇具有很好參考價值的文章主要介紹了一文帶你了解動態(tài)內(nèi)存管理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

目錄

動態(tài)內(nèi)存存在的意義

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

malloc和free

calloc

realloc

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

對NULL指針解引用操作

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

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

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

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

動態(tài)開辟內(nèi)存忘記釋放

經(jīng)典的筆試題

C/C++程序的內(nèi)存開辟

柔性數(shù)組?

柔性數(shù)組的特點(diǎn)

柔性數(shù)組的使用

柔性數(shù)組的優(yōu)點(diǎn)


動態(tài)內(nèi)存存在的意義

int a = 10;
int arr[10] = { 0 };

上面變量開辟的空間有兩個特點(diǎn):
空間開辟的大小是固定的

數(shù)組在聲明的時候,必須指定數(shù)組的長度,它需要的內(nèi)存在編譯時分配

但是,我們有的時候空間的需要大小在程序運(yùn)行的時候才知道,數(shù)組的編譯是開辟空間的方式就不能滿足了。這時候就需要動態(tài)內(nèi)存開辟了。

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

malloc和free

void* malloc (size_t size)

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

?malloc函數(shù)向內(nèi)存申請一塊連續(xù)可用的空間,返回指向這塊空間的指針。

注意:
如果開辟成功,則返回一個指向這塊空間的指針。、

如果開辟失敗,則返回一個空指針,使用malloc的返回值要做檢查

返回值的類型是void*類型,malloc不知道開辟空間的類型,需要使用者自己來決定。

如果size為0,malloc的行為是屬于標(biāo)準(zhǔn)未定義的

C語言還提供了另一個函數(shù)free,是用來釋放動態(tài)內(nèi)存的。

void free (void* ptr)

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

?free函數(shù)是用來釋放動態(tài)開辟的內(nèi)存

如果參數(shù)ptr指向的不是動態(tài)開辟的空間,這種行為是標(biāo)準(zhǔn)未定義的。

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

malloc和free的聲明都在stdlib.h中

舉個栗子:

要注意把ptr變?yōu)镹ULL,不然它就是野指針了

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int arr[10] = { 0 };
	int* ptr = (int*)malloc(40);
	if (ptr == NULL)
		return 1;
	for (int i = 0; i < 20; i++)
	{
		*(ptr + i) = i;
	}
	free(ptr); //釋放空間
	ptr = NULL;//把ptr變?yōu)镹ULL,不然他是野指針
	return 0;
}

calloc

void* calloc (size_t num, size_t size)

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

?calloc將num個大小為size的元素初始化為0

與malloc的區(qū)別在于calloc會在返回地址前將申請的空間全部初始化為0

int main()
{
	int* ptr = (int*)calloc(10, sizeof(int));
	if (ptr == NULL)
		return 1;
	for (int i = 0; i < 10; i++)
	{
		printf("%d\n",*(ptr + i));
	}
	free(ptr);
	ptr = NULL;
	return 0;
}

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

realloc

void* realloc (void* ptr, size_t size)

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

?realloc的出現(xiàn)可以讓動態(tài)內(nèi)存管理變得更加靈活。有時我們會發(fā)現(xiàn)過去申請的空間太小了,又有時覺得太大了。為了合理管理內(nèi)存,我們一定會對內(nèi)存的大小進(jìn)行調(diào)整。realloc就可以做做到對動態(tài)開辟內(nèi)存大小地調(diào)整。

ptr是要調(diào)整內(nèi)存地地址

size是調(diào)整后的大小

返回值為調(diào)整之后的內(nèi)存起始位置

這個函數(shù)調(diào)整原內(nèi)存空間大小的基礎(chǔ)上,會將原空間上的數(shù)據(jù)移動到新的空間

realloc在調(diào)整原內(nèi)存空間有兩種情況:
1 原有空間之后有足夠大的空間

2 原有空間之后沒有足夠大的空間

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

情況一:要擴(kuò)展內(nèi)存的時候就直接在原有內(nèi)存后面追加空間,原來空間的數(shù)據(jù)不發(fā)生變化。

情況二:原有空間之后沒有足夠的空間時,會在對堆上找另一塊空間來使用,函數(shù)返回的就是這個新的內(nèi)存地址。?

?栗子:

int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
		return 1;
	for (int i = 0; i < 10; i++)
	{
		*(p + i) = i;
	}

	int* ptr = (int*)realloc(p, 50);
	if (ptr == NULL)
		return 1;
	p = ptr;
	ptr = NULL;
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", *(p + i));
	}
	free(p);
	p = NULL;
	return 0;
}

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

對NULL指針解引用操作

void test()
{
 int *p = (int *)malloc(INT_MAX/4);
 *p = 20;//如果p的值是NULL,就會有問題
 free(p);
}

這里沒有對p進(jìn)行判斷,如果malloc申請空間失敗的話,他就會為空指針,對空指針解引用就會出現(xiàn)問題。

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

void test()
{
 int i = 0;
 int *p = (int *)malloc(10*sizeof(int));
 if(NULL == p)
 {
 exit(EXIT_FAILURE);
 }
 for(i=0; i<=10; i++)
 {
 *(p+i) = i;//當(dāng)i是10的時候越界訪問
 }
 free(p);
}

觀察代碼我們發(fā)現(xiàn),當(dāng)i等于10時,會越界訪問,導(dǎo)致不可控的因素。

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

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

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

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

p指針移動后釋放會導(dǎo)致一部分內(nèi)存無法釋放

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

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

動態(tài)開辟內(nèi)存忘記釋放

void test()
{
 int *p = (int *)malloc(100);
 if(NULL != p)
 {
 *p = 20;
 }
}
int main()
{
 test();
 while(1);
}

忘記釋放動態(tài)開辟的內(nèi)存這樣會導(dǎo)致內(nèi)存泄露,使這部分內(nèi)存無法再使用

經(jīng)典的筆試題

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

這段代碼里面的str是傳值調(diào)用,這函數(shù)將str重新拷貝了一份,函數(shù)接受這個函數(shù)就銷毀了,str還是NULL,則strcpy不能使用,printf也打印不出

char *GetMemory(void)
{
 char p[] = "hello world";
 return p;
}
void Test(void)
{
 char *str = NULL;
 str = GetMemory();
 printf(str);
}

這里返回的p是野指針,因?yàn)槌隽撕瘮?shù)p開辟的空間就銷毀了,p指向的內(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);
}

這里雖然是傳址調(diào)用,但是到最后它沒有將開辟的空間釋放掉,導(dǎo)致內(nèi)存泄露。

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

這里是提前釋放了空間,讓后面的拷貝的地址后沒有地方被他們存放

C/C++程序的內(nèi)存開辟

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

內(nèi)存分配的區(qū)域:

棧區(qū)(stack):在執(zhí)行函數(shù)時,函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)
束時這些存儲單元自動被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是
分配的內(nèi)存容量有限。 棧區(qū)主要存放運(yùn)行函數(shù)而分配的局部變量、函數(shù)參數(shù)、返回?cái)?shù)據(jù)、返
回地址等。

?堆區(qū)(heap):一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收 。

數(shù)據(jù)段(靜態(tài)區(qū))(static)存放全局變量、靜態(tài)數(shù)據(jù)。程序結(jié)束后由系統(tǒng)釋放。
代碼段:存放函數(shù)體(類成員函數(shù)和全局函數(shù))的二進(jìn)制代碼。
對于static的解釋?:
實(shí)際上普通的局部變量是在棧區(qū)分配空間的,棧區(qū)的特點(diǎn)是在上面創(chuàng)建的變量出了作用域就銷毀。
但是被static修飾的變量存放在數(shù)據(jù)段(靜態(tài)區(qū)),數(shù)據(jù)段的特點(diǎn)是在上面創(chuàng)建的變量,直到程序
結(jié)束才銷毀 所以生命周期變長

一文帶你了解動態(tài)內(nèi)存管理,# 系統(tǒng)解析C語言,C語言,數(shù)據(jù)結(jié)構(gòu),c語言

柔性數(shù)組?

C99 中,結(jié)構(gòu)中的最后一個元素允許是未知大小的數(shù)組,這就叫做『柔性數(shù)組』成員。
struct st_type
{
 int i;
 int a[0];//柔性數(shù)組成員
};
struct st_type
{
 int i;
 int a[];//柔性數(shù)組成員
};

有些編譯器可以使用第一種方法,有些可以使用第二種方法

柔性數(shù)組的特點(diǎn)

結(jié)構(gòu)體中的柔性成員前面至少得有一個其他的成員

sizeof求這種結(jié)構(gòu)的大小不會包括柔性數(shù)組

包括柔性數(shù)組成員的結(jié)構(gòu)用malloc進(jìn)行動態(tài)內(nèi)存分配的時候,分配的內(nèi)存應(yīng)該大于結(jié)構(gòu)體的大小,以便適用柔性數(shù)組的預(yù)期大小

typedef struct st_type
{
 int i;
 int a[0];//柔性數(shù)組成員
}type_a;
printf("%d\n", sizeof(type_a));//輸出的是4

柔性數(shù)組的使用

typedef struct st_type
{
 int i;
 int a[0];//柔性數(shù)組成員
}type_a;

int i = 0;
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
//業(yè)務(wù)處理
p->i = 100;
for(i=0; i<100; i++)
{
 p->a[i] = i;
}
free(p);

這個柔性數(shù)組,相當(dāng)于獲得了100個整型的連續(xù)空間

柔性數(shù)組的優(yōu)點(diǎn)

上面的代碼其實(shí)也可以這樣設(shè)計(jì):文章來源地址http://www.zghlxwxcb.cn/news/detail-595598.html

typedef struct st_type
{
	int i;
int* p_a;
}type_a;
type_a* p = (type_a*)malloc(sizeof(type_a));
p->i = 100;
p->p_a = (int*)malloc(p->i * sizeof(int));
//業(yè)務(wù)處理
for (i = 0; i < 100; i++)
{
	p->p_a[i] = i;
}
//釋放空間
free(p->p_a);
p->p_a = NULL;
free(p);
p = NULL;
上述 代碼1 代碼2 可以完成同樣的功能,但是 方法1 的實(shí)現(xiàn)有兩個好處:
第一個好處是:方便內(nèi)存釋放
如果我們的代碼是在一個給別人用的函數(shù)中,你在里面做了二次內(nèi)存分配,并把整個結(jié)構(gòu)體返回給
用戶。用戶調(diào)用free可以釋放結(jié)構(gòu)體,但是用戶并不知道這個結(jié)構(gòu)體內(nèi)的成員也需要free,所以你
不能指望用戶來發(fā)現(xiàn)這個事。所以,如果我們把結(jié)構(gòu)體的內(nèi)存以及其成員要的內(nèi)存一次性分配好
了,并返回給用戶一個結(jié)構(gòu)體指針,用戶做一次free就可以把所有的內(nèi)存也給釋放掉。
第二個好處是:這樣有利于訪問速度.
連續(xù)的內(nèi)存有益于提高訪問速度,也有益于減少內(nèi)存碎片

到了這里,關(guān)于一文帶你了解動態(tài)內(nèi)存管理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 不知道該學(xué)那一個語言?一文帶你了解三門語言

    名字:阿玥的小東東 學(xué)習(xí):Python。正在學(xué)習(xí)c++ 主頁:阿玥的小東東 目錄 粉絲留言,回答問題 1.首先,初步了解?

    2024年02月21日
    瀏覽(17)
  • MAVEN利器:一文帶你了解MAVEN中的依賴管理

    MAVEN利器:一文帶你了解MAVEN中的依賴管理

    強(qiáng)大的構(gòu)建工具——Maven。作為Java生態(tài)系統(tǒng)中的重要組成部分,Maven為開發(fā)人員提供了一種簡單而高效的方式來構(gòu)建、管理和發(fā)布Java項(xiàng)目。無論是小型項(xiàng)目還是大型企業(yè)級應(yīng)用,Maven都能幫助開發(fā)人員輕松處理依賴管理、編譯、測試和部署等任務(wù)。 在上一篇文章中,我們學(xué)習(xí)

    2024年02月10日
    瀏覽(32)
  • 【C語言】-- 一篇帶你了解指針,內(nèi)存,解引用

    【C語言】-- 一篇帶你了解指針,內(nèi)存,解引用

    目錄 1、什么是指針? 1.1 內(nèi)存 1.2 指針變量 二、指針和指針類型 1、指針類型 2、指針+整數(shù) 3、指針的解引用 三、野指針 1、野指針成因 (1) 指針未初始化 (2) 指針越界訪問 (3) 指針指向的空間釋放 2、如何規(guī)避野指針 四、指針運(yùn)算 1、指針-指針 ? ? ? ?本篇文章我們來了解C語

    2024年02月16日
    瀏覽(33)
  • c語言:通訊錄管理系統(tǒng)(動態(tài)分配內(nèi)存版)

    c語言:通訊錄管理系統(tǒng)(動態(tài)分配內(nèi)存版)

    前言: 本通訊錄管理系統(tǒng)一共三個版本,除此文章以外還有如下倆個版本,大家可以根據(jù)需求自?。?基礎(chǔ)增刪查改功能版本 :c語言:通訊錄管理系統(tǒng)(增刪查改)_luming.02的博客-CSDN博客 文件保存版本 :c語言:通訊錄管理系統(tǒng)(文件版本)-CSDN博客 ????????本文是在基

    2024年02月08日
    瀏覽(104)
  • 動態(tài)內(nèi)存管理函數(shù)介紹及C語言實(shí)現(xiàn)通訊錄管理系統(tǒng)2.0版(動態(tài)增長版本)

    動態(tài)內(nèi)存管理函數(shù)介紹及C語言實(shí)現(xiàn)通訊錄管理系統(tǒng)2.0版(動態(tài)增長版本)

    之前向大家介紹了C語言實(shí)現(xiàn)通訊錄管理系統(tǒng)1.0版本,但該版本有明顯的不足之處,比如:一開始就開辟了1000個date數(shù)組,如果聯(lián)系人很少,那么就會造成嚴(yán)重的內(nèi)存浪費(fèi),或者聯(lián)系人超過了1000人,那么原數(shù)組就放不下了,所以今天我們考慮使用動態(tài)內(nèi)存管理的辦法來實(shí)現(xiàn)一個

    2023年04月08日
    瀏覽(21)
  • 一文帶你了解:Linux 文件系統(tǒng)+文件系統(tǒng)相關(guān) Shell 命令+文件系統(tǒng)類型

    一文帶你了解:Linux 文件系統(tǒng)+文件系統(tǒng)相關(guān) Shell 命令+文件系統(tǒng)類型

    本篇文章是記錄我在學(xué)習(xí)Linux時,有關(guān)Linux?文件系統(tǒng)的學(xué)習(xí)。 操作系統(tǒng)的基本功能之一就是文件管理,而文件的管理是由文件系統(tǒng)來完成的。 Linux 支持多種文件系統(tǒng),接下來我們就來一起了解 Linux 下的 文件系統(tǒng)、文件系統(tǒng)類型、文件系統(tǒng)結(jié)構(gòu)和文件系統(tǒng)相關(guān) Shell 命令。 有

    2024年02月22日
    瀏覽(21)
  • 【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū)

    【C語言】-- 一篇帶你了解C語言內(nèi)存五大區(qū)——棧區(qū),堆區(qū),全局區(qū),常量區(qū),代碼區(qū)

    目錄 1 C語言的內(nèi)存分區(qū) 1.1 內(nèi)存五大分區(qū) 1.2 內(nèi)存分區(qū)簡介 1.2.1 棧區(qū)(stack) 1.2.2 堆區(qū)(heap) 1.2.3 (全局)靜態(tài)區(qū) 1.2.4 常量區(qū) 1.2.5 代碼區(qū) 創(chuàng)作不易,如果本篇博客對您有一定的幫助,大家記得留言+點(diǎn)贊哦。 C語言已經(jīng)持續(xù)學(xué)習(xí)一段時間了,今天特此總結(jié)一下關(guān)于C語言內(nèi)存的五大區(qū)

    2024年02月16日
    瀏覽(24)
  • 微軟Windows 11正式發(fā)布!一文帶你了解免費(fèi)升級方法、最低系統(tǒng)要求

    微軟Windows 11正式發(fā)布!一文帶你了解免費(fèi)升級方法、最低系統(tǒng)要求

    2.備份用戶所有的重要文件、應(yīng)用程序和數(shù)據(jù)。 3.在用戶的Windows 10電腦上,進(jìn)入設(shè)置更新和安全Windows更新。 4.檢查更新。 5.如果有免費(fèi)的Windows 11升級,用戶會看到一個下載和安裝的選項(xiàng)。 點(diǎn)擊“下載和安裝”后,按照屏幕上的提示,配置Windows 11設(shè)置。 如果用戶沒有看到免

    2024年03月26日
    瀏覽(19)
  • C語言 — 動態(tài)內(nèi)存管理(動態(tài)內(nèi)存函數(shù))

    C語言 — 動態(tài)內(nèi)存管理(動態(tài)內(nèi)存函數(shù))

    本期分為三篇介紹動態(tài)內(nèi)存管理相關(guān)內(nèi)容,關(guān)注博主了解更多 博主博客鏈接:https://blog.csdn.net/m0_74014525 本期介紹動態(tài)內(nèi)存函數(shù),函數(shù)如何使用、函數(shù)格式、在使用在所需要的注意點(diǎn)及C/C++程序的內(nèi)存開辟區(qū)域 第一篇:C語言 — 動態(tài)內(nèi)存管理(動態(tài)內(nèi)存函數(shù)) 第二篇:C語言

    2024年02月14日
    瀏覽(21)
  • 【C語言】動態(tài)內(nèi)存管理

    【C語言】動態(tài)內(nèi)存管理

    大家好,我是蘇貝,本篇博客帶大家了解動態(tài)內(nèi)存管理,如果你覺得我寫的還不錯的話,可以給我一個贊??嗎,感謝?? 我們已經(jīng)掌握的內(nèi)存開辟方式有: int val = 20; 在??臻g上開辟四個字節(jié) char arr[10] = {0}; 在棧空間上開辟10個字節(jié)的連續(xù)空間 但是上述的開辟空間的方式有

    2024年01月16日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包