自己怎么做獨(dú)立網(wǎng)站整站排名服務(wù)
文章目錄
- 前言
- 一、為什么存在動(dòng)態(tài)內(nèi)存管理
- 二、動(dòng)態(tài)內(nèi)存函數(shù)的介紹
- 1. malloc函數(shù)
- 2. 內(nèi)存泄漏
- 3. 動(dòng)態(tài)內(nèi)存開辟位置
- 4. free函數(shù)
- 5. calloc 函數(shù)
- 6. realloc 函數(shù)
- 7. realloc 傳空指針
- 總結(jié)
前言
C語言動(dòng)態(tài)內(nèi)存管理malloc、calloc、realloc、free函數(shù)、內(nèi)存泄漏、動(dòng)態(tài)內(nèi)存開辟的位置等的介紹
一、為什么存在動(dòng)態(tài)內(nèi)存管理
int a = 0;
int arr[5] = {0};
- 上述的開辟空間的方式有兩個(gè)特點(diǎn):
- 空間開辟大小是固定的。
- 數(shù)組在聲明的時(shí)候,必須指定數(shù)組的長度,它所需要的內(nèi)存在編譯時(shí)分配。
但是對(duì)于空間的的需求,不僅僅是上述的情況
有時(shí)候,我們需要的空間大小在程序運(yùn)行的時(shí)候才能知道,上述的編譯時(shí)開辟空間的方式就不能滿足了。
這時(shí)候就只能用動(dòng)態(tài)內(nèi)存開辟了。
二、動(dòng)態(tài)內(nèi)存函數(shù)的介紹
1. malloc函數(shù)
- malloc 函數(shù)需要引入頭文件 <stdlib.h>
C語言提供了一個(gè)動(dòng)態(tài)內(nèi)存開辟的函數(shù):
void* malloc(size_t size);
這個(gè)函數(shù)向內(nèi)存申請(qǐng)了一塊連續(xù)可用的空間,并返回指向這塊空間的指針。
- 如果開辟成功,則返回一個(gè)指向開辟好空間的指針。
- 如果開辟失敗,則返回一個(gè)NULL指針,因此malloc的返回值一定要做檢查。
- 返回值的類型是 void* ,所以malloc函數(shù)并不知道開辟空間的類型,具體在使用的時(shí)候使用者自己來決定。
- size 指的是 size 個(gè) 字節(jié) 的大小的空間
- 如果參數(shù) size 為 0, malloc 的行為是標(biāo)準(zhǔn)未定義的,取決于編譯器。
- 動(dòng)態(tài)開辟40個(gè)字節(jié)大小的空間
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{int arr[10] = { 0 };int* p = (int*)malloc(40); // malloc 開辟 40 個(gè)字節(jié)大小的內(nèi)存空間// 檢驗(yàn)如果 動(dòng)態(tài)內(nèi)存開辟失敗,打印錯(cuò)誤信息,終止程序if (NULL == p){printf("%s\n", strerror(errno));return 1;}int i = 0;for (i = 0; i < 10; i++){*(p + i) = i;}for (i = 0; i < 10; i++){printf("%d ", *(p + i)); // 0 1 2 3 4 5 6 7 8 9}return 0;
}
- 需要開辟的內(nèi)存空間過大返回空指針
INT_MAX 是定義的一個(gè) 21億多的一個(gè)數(shù)字
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{int arr[10] = { 0 };int* p = (int*)malloc(INT_MAX * 2); // malloc 開辟 INT_MAX * 2 個(gè)字節(jié)大小的內(nèi)存空間// 檢驗(yàn)如果 動(dòng)態(tài)內(nèi)存開辟失敗,打印錯(cuò)誤信息,終止程序if (NULL == p){printf("%s\n", strerror(errno));return 1;}int i = 0;for (i = 0; i < 10; i++){*(p + i) = i;}for (i = 0; i < 10; i++){printf("%d ", *(p + i)); // Not enough space}return 0;
}
2. 內(nèi)存泄漏
- 如果一個(gè)程序在向內(nèi)存申請(qǐng)空間后,沒有釋放申請(qǐng)的空間,則在程序結(jié)束的時(shí)候,系統(tǒng)會(huì)自動(dòng)回收內(nèi)存空間
- 如果一個(gè)程序在向內(nèi)存申請(qǐng)空間后,沒有釋放申請(qǐng)的空間, 并且程序在持續(xù)運(yùn)行,短時(shí)間不結(jié)束,此時(shí)就存在內(nèi)存泄漏。
3. 動(dòng)態(tài)內(nèi)存開辟位置
- 動(dòng)態(tài)內(nèi)存開辟在堆區(qū)。
- 局部變量等開辟在棧區(qū)。
4. free函數(shù)
C語言提供了一個(gè)函數(shù)free,專門是用來做動(dòng)態(tài)內(nèi)存的釋放和回收的
void free (void* ptr);
free 函數(shù)是用來釋放動(dòng)態(tài)開辟的內(nèi)存。
- 如果參數(shù) ptr 指向的空間不是動(dòng)態(tài)開辟的,那free函數(shù)的 行為是未定義的。
- 如果參數(shù) ptr 是 NULL 指針,則函數(shù)什么事都不做。
- malloc 和 free 函數(shù)都聲明在 <stdlib.h>頭文件中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{int arr[10] = { 0 };int* p = (int*)malloc(40); // malloc 開辟 40 個(gè)字節(jié)大小的內(nèi)存空間// 檢驗(yàn)如果 動(dòng)態(tài)內(nèi)存開辟失敗,打印錯(cuò)誤信息,終止程序if (NULL == p){printf("%s\n", strerror(errno));return 1;}int i = 0;for (i = 0; i < 10; i++){*(p + i) = i;}for (i = 0; i < 10; i++){printf("%d ", *(p + i)); // 0 1 2 3 4 5 6 7 8 9}free(p);p = NULL;return 0;
}
- free (p) 就會(huì) 將申請(qǐng)40個(gè)字節(jié)的動(dòng)態(tài)內(nèi)存空間 釋放掉。
- 但是 p 依然存放著 之前接收的動(dòng)態(tài)內(nèi)存的地址,會(huì)變成野指針。
- 所以 在 釋放完p 的空間后 將p 重置為 NULL指針。
5. calloc 函數(shù)
C語言還提供另外一個(gè)叫 calloc,calloc,函數(shù)也用來動(dòng)態(tài)內(nèi)存分配。
void* calloc(size_t num, size_t size);
- 函數(shù)功能是為num個(gè)大小為size的元素開辟一塊空間,并且把空間的每個(gè)字節(jié)初始化為0。
- 與函數(shù) malloc 的區(qū)別只在于 calloc 會(huì)在返回地址之前把申請(qǐng)的空間的每個(gè)字節(jié)初始化為全0。
- 需要初始化時(shí),用 calloc, 不需要初始化 用 malloc。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{int* p = (int*)calloc(10, sizeof(int)); // 開辟 10 個(gè) int類型大小 的空間if (NULL == p){printf("%s\n", strerror(errno));return 1;}int i = 0;for (i = 0; i < 10; i++){// 自動(dòng)初始化為全 0printf("%d ", *(p + i)); // 0 0 0 0 0 0 0 0 0 0 }free(p);p = NULL;return 0;
}
6. realloc 函數(shù)
- realloc 函數(shù)的出現(xiàn)讓動(dòng)態(tài)內(nèi)存管理更加靈活
- realloc函數(shù)可以做到對(duì)動(dòng)態(tài)開辟內(nèi)存大小的調(diào)整
void* realloc(void* ptr, size_t size);
- ptr 是要調(diào)整的內(nèi)存地址
- size 調(diào)整之后新大小
- 返回值為調(diào)整之后的內(nèi)存起始位置。
- 這個(gè)函數(shù)調(diào)整原內(nèi)存空間大小的基礎(chǔ)上,還會(huì)將原來內(nèi)存中的數(shù)據(jù)移動(dòng)到新的空間。
- realloc在調(diào)整內(nèi)存空間的時(shí)候存在兩種情況:
- 1: 原有空間之后有足夠大的空間。
- 2: 原有空間之后的空間不夠或被占用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{int* p = (int*)malloc(40); // 開辟 10 個(gè) int類型大小 的空間if (NULL == p){printf("%s\n", strerror(errno));return 1;}int i = 0;// 使用for (i = 0; i < 10; i++){*(p + i) = i + 1;}// 擴(kuò)容int* str = (int*)realloc(p, 80);if (str != NULL){p = str;}// 使用for (i = 10; i < 20; i++){*(p + i) = i + 1;}for (i = 0; i < 20; i++){printf("%d ", *(p + i)); // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20}free(p);p = NULL;return 0;
}
7. realloc 傳空指針
- realloc傳空指針 和 malloc是等價(jià)的。
#include <stdio.h>
int main()
{int* p = realloc(NULL, 40);// 此時(shí) realloc 和 malloc(40)是等價(jià)的return 0;
}
總結(jié)
C語言動(dòng)態(tài)內(nèi)存管理malloc、calloc、realloc、free函數(shù)、內(nèi)存泄漏、動(dòng)態(tài)內(nèi)存開辟的位置等的介紹