日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言-动态内存管理

發(fā)布時(shí)間:2023/12/18 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言-动态内存管理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

C語言中,我們?cè)谑褂脭?shù)組的時(shí)候,經(jīng)常有這樣的一個(gè)問題:數(shù)組在申明的時(shí)候,必須指定數(shù)組的長度,它所需要的內(nèi)存在編譯時(shí)分配。有的時(shí)候,我們開辟的空間太小,無法滿足我們的需求,有時(shí)又太大,浪費(fèi)空間比較嚴(yán)重。那么能不能按照需求,需要一個(gè)就開辟一個(gè)空間,需要兩個(gè)就開辟兩個(gè)空間? 這時(shí)候就只能試試動(dòng)態(tài)內(nèi)存開辟了。

一、malloc 函數(shù)和free 函數(shù)

C語言提供了一個(gè)用來動(dòng)態(tài)開辟的函數(shù):malloc函數(shù)。頭文件是stdlib.h。

void* malloc (size_t size);

該函數(shù)能夠在內(nèi)存中申請(qǐng)一塊連續(xù)可用的空間,如果開辟成功,就返回這個(gè)開辟好空間的指針,否則,就返回NULL。因此,在使用malloc的時(shí)候,一定要對(duì)函數(shù)的返回值做檢查,避免空指針引用。由于malloc函數(shù)不知道要開辟的空間是什么類型,所以在使用的時(shí)候,一般要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。

free 函數(shù)是用來進(jìn)行動(dòng)態(tài)內(nèi)存的釋放和回收的。頭文件是stdlib.h。

void free (void* ptr);

free函數(shù)只能對(duì)動(dòng)態(tài)內(nèi)存的函數(shù)進(jìn)行釋放。如果不是指向的空間不是動(dòng)態(tài)開辟的,那么free函數(shù)的結(jié)果都是未定義的。

#include<stdio.h>
#include<stdlib.h>
?
int main(void)
{
?? ?int* a = (int*)malloc(sizeof(int));//給a動(dòng)態(tài)開辟空間
?? ?
?? ?free(a);
? ? a = NULL;
?? ?return 0;
}

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?給a申請(qǐng)空間

?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?free(a)
?上面的例子只是單純的說明malloc函數(shù)的用法。要注意的是,一般情況下,一定要對(duì)malloc函數(shù)的返回值做檢查,同時(shí),在使用完成malloc函數(shù)之后,要及時(shí)的進(jìn)行釋放。同時(shí),對(duì)引用的指針賦值為空。否則,上面的a就成為了野指針,在后面再次使用的時(shí)候就會(huì)導(dǎo)致出現(xiàn)非法訪問的問題。

二、calloc 函數(shù)

calloc 函數(shù)的功能是為 num 個(gè)大小為 size 的元素開辟一塊空間,并且把空間的每個(gè)字節(jié)初始化為0。與函數(shù) malloc 的區(qū)別只在于 calloc 會(huì)在返回地址之前把申請(qǐng)的空間的每個(gè)字節(jié)初始化為全0。

void* calloc (size_t num, size_t size);

#include<stdio.h>
#include<stdlib.h>
?
int main(void)
{
?? ?int* p = (int*)calloc(10, sizeof(int));//給p動(dòng)態(tài)開辟空間
?
?? ?free(p);
?? ?return 0;
}


三、realloc 函數(shù)

?

有的時(shí)候我們使用malloc函數(shù)之后,發(fā)現(xiàn)申請(qǐng)的空間還是太小,有的時(shí)候太大,想要再次進(jìn)行修改,這個(gè)時(shí)候就可以使用realloc函數(shù)。頭文件是stdlib.h。

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

?ptr 是要調(diào)整的內(nèi)存地址,size 是調(diào)整之后新大小。返回值是調(diào)整之后的內(nèi)存的起始位置。

?

realloc函數(shù)進(jìn)行調(diào)整的時(shí)候,有以下方式:

1,如果原有空間后面有足夠大的空間,就直接擴(kuò)展。

2,另找一塊滿足要求的空間將原有空間的值進(jìn)行拷貝,同時(shí)返回新的空間地址。

realloc函數(shù)的返回結(jié)果在使用時(shí)也要進(jìn)行返回值是否為NULL的判斷。?

?

?四、常見的內(nèi)存錯(cuò)誤

1,對(duì)NULL指針解引用操作

#include<stdio.h>
#include<stdlib.h>
?
void test()
{
?? ?int* p = (int*)malloc(INT_MAX / 4);
?? ?if (p != NULL)
?? ?{
?? ??? ?*p = 20;//如果p的值是NULL,就會(huì)有問題,要進(jìn)行判斷
?? ??? ?printf("%d", *p);//20
?? ?}
?? ?else
?? ?{
?? ??? ?printf("為空!");
?? ?}
?
?? ?free(p);
}
?
int main(void)
{
?? ?test();
?? ?return 0;
}
2,對(duì)動(dòng)態(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的時(shí)候越界訪問
?? ?}
?? ?free(p);
}
?
?
int main(void)
{
?? ?test();
?? ?return 0;
}
程序就會(huì)崩潰。

?

3,對(duì)非動(dòng)態(tài)開辟的空間進(jìn)行free釋放

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

?

?4,只釋放動(dòng)態(tài)開辟內(nèi)存的一部分

void test()
{
?? ?int* p = (int*)malloc(100);
?? ?p++;
?? ?free(p);//p不再指向動(dòng)態(tài)內(nèi)存的起始位置
}
?
int main(void)
{
?? ?test();
?
?? ?return 0;
}
結(jié)果同上。

5,多次釋放同一塊內(nèi)存。

void test()
{
?? ?int* p = (int*)malloc(100);
?? ?free(p);
?? ?free(p);//重復(fù)釋放
}
?
int main(void)
{
?? ?test();
?
?? ?return 0;
}
還是同樣的結(jié)果。

6,忘記釋放,造成內(nèi)存泄露。

void test()
{
?? ?int* p = (int*)malloc(100);
?? ?if (NULL != p)
?? ?{
?? ??? ?*p = 20;
?? ?}
}
int main()
{
?? ?test();
?? ?while (1);
}
動(dòng)態(tài)內(nèi)存的開辟是在堆上開辟的,這里面的內(nèi)存需要自己手動(dòng)來進(jìn)行釋放,如果不釋放,在最后程序結(jié)束的時(shí)候可能由系統(tǒng)自動(dòng)回收。

我們平時(shí)寫的變量等在棧,數(shù)據(jù)段(存放全局變量,靜態(tài)變量)等中,這些不需要手動(dòng)釋放,他們有自己的作用域,出了這個(gè)作用域就會(huì)自動(dòng)被銷毀。而在堆上開辟的空間需要手動(dòng)來釋放。
?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的C语言-动态内存管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。