C語(yǔ)言深入講解動(dòng)態(tài)內(nèi)存分配函數(shù)的使用
局部變量和函數(shù)的形參向棧區(qū)申請(qǐng)空間
全局變量和static靜態(tài)變量向靜態(tài)區(qū)申請(qǐng)空間
動(dòng)態(tài)內(nèi)存分配向堆區(qū)申請(qǐng)空間(位于<stdlib.h>或<cstdlib>頭文件)
一、malloc
void* malloc (size_t size);
分配內(nèi)存塊
分配一個(gè)連續(xù)可用的字節(jié)內(nèi)存塊,返回指向該內(nèi)存塊開頭的指針。
新分配的內(nèi)存塊的內(nèi)容未初始化,內(nèi)存塊中的數(shù)據(jù)為不確定值。
如果為參數(shù)為零,則返回值取決于特定的庫(kù)實(shí)現(xiàn)(它可能是空指針,也可能不是空指針)。
參數(shù)
內(nèi)存塊的大小,以字節(jié)為單位。
是無(wú)符號(hào)整數(shù)類型,size_t。
返回值
成功時(shí),為指向函數(shù)分配的內(nèi)存塊的指針。
此指針的類型始終為void*,可以將其轉(zhuǎn)換為所需的數(shù)據(jù)指針類型。(C++由于其類型檢查更為嚴(yán)格,則必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換)
如果函數(shù)未能分配請(qǐng)求的內(nèi)存塊,則返回空指針NULL。
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<stdio.h>
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
else
{
for (int i = 0; i < 10; ++i)
{
*(p + i) = i;
}
for (int i = 0; i < 10; ++i)
{
printf("%d ", *(p + i));
}
}
free(p);
p = NULL;
/*
1.斷開指針與動(dòng)態(tài)開辟的空間的聯(lián)系,避免指針的危險(xiǎn)操作
2.防止對(duì)同一塊動(dòng)態(tài)空間內(nèi)存空間的重復(fù)釋放
*/
return 0;
}輸出
0 1 2 3 4 5 6 7 8 9
二、free(用于釋放動(dòng)態(tài)開辟的空間)
void free(void* ptr);
解除分配內(nèi)存塊
1.若參數(shù)ptr指向的空間不是動(dòng)態(tài)開辟的,那么free函數(shù)的行為是未定義的。
2.若參數(shù)ptr是NULL指針,則free函數(shù)什么也不做。
3.free只釋放堆區(qū)空間,但ptr仍指向那塊空間。所以使用完free后要將ptr置為NULL,切斷ptr與該內(nèi)存塊的聯(lián)系。
參數(shù)
指向要釋放的那塊空間的指針(必須指向初始位置)
返回值
無(wú)
錯(cuò)誤案例
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = (int*)malloc(sizeof(int) * 10);
if (p == NULL)
{
return 1;
}
for (int i = 0; i < 10; ++i)
{
*(p + i) = i;
}
for (int i = 0; i < 10; ++i)
{
printf("%d ", *(p++));//這里指針移動(dòng)
}
free(p);//導(dǎo)致free釋放的不是初始位置的指針,程序崩潰
p = NULL;
return 0;
}三、calloc
void* calloc(size_t num,size_t num);
分配和零初始化內(nèi)存塊
1.函數(shù)的功能是為num個(gè)大小為size的元素開辟空間。
2.與malloc的區(qū)別只在于calloc會(huì)在返回地址前將申請(qǐng)的空間的每個(gè)字母初始化為0。
#include <stdio.h> /* printf, scanf, NULL */
#include <stdlib.h> /* calloc, exit, free */
int main ()
{
int i,n;
int * pData;
printf ("Amount of numbers to be entered: ");
scanf ("%d",&i);
pData = (int*) calloc (i,sizeof(int));
if (pData==NULL) exit (1);
for (n=0;n<i;n++)
{
printf ("Enter number #%d: ",n+1);
scanf ("%d",&pData[n]);
}
printf ("You have entered: ");
for (n=0;n<i;n++) printf ("%d ",pData[n]);
free (pData);
return 0;
}四、realloc
void* realloc(void* ptr,size_t size);
重新分配內(nèi)存塊
1.ptr為要調(diào)整的內(nèi)存空間,size為調(diào)整后的新大小
2.返回值為調(diào)整后的內(nèi)存塊的起始位置
注意事項(xiàng)
1.若ptr指向的空間之后有足夠的空間可以追加,則直接追加,然后返回ptr。
2.若ptr指向的空間之后沒(méi)有足夠的內(nèi)存空間,則realloc函數(shù)會(huì)重新找一塊內(nèi)存空間,開辟一塊滿足需求的內(nèi)存空間,并且把原來(lái)內(nèi)存中的數(shù)據(jù)拷貝過(guò)來(lái),釋放舊的內(nèi)存空間,最后返回新開辟的內(nèi)存空間的地址。
#include <stdio.h> /* printf, scanf, puts */
#include <stdlib.h> /* realloc, free, exit, NULL */
int main ()
{
int input,n;
int count = 0;
int* numbers = NULL;
int* more_numbers = NULL;
do {
printf ("Enter an integer value (0 to end): ");
scanf ("%d", &input);
count++;
more_numbers = (int*) realloc (numbers, count * sizeof(int));
if (more_numbers!=NULL) {
numbers=more_numbers;
numbers[count-1]=input;
}
else {
free (numbers);
puts ("Error (re)allocating memory");
exit (1);
}
} while (input!=0);
printf ("Numbers entered: ");
for (n=0;n<count;n++) printf ("%d ",numbers[n]);
free (numbers);
return 0;
}五、常見的動(dòng)態(tài)內(nèi)存分配錯(cuò)誤
1.對(duì)NULL指針的解引用操作(要進(jìn)行返回值的判斷)
2.對(duì)動(dòng)態(tài)開辟空間的越界訪問(wèn)
3.對(duì)非動(dòng)態(tài)開辟內(nèi)存的空間的使用free進(jìn)行釋放
4.使用free釋放一塊動(dòng)態(tài)開辟內(nèi)存的一部分
(若指針位置發(fā)生變化,歸位后再進(jìn)行釋放)
5.對(duì)同一塊動(dòng)態(tài)內(nèi)存的多次釋放
6.動(dòng)態(tài)開辟內(nèi)存忘記釋放(內(nèi)存泄漏)
六、柔性數(shù)組
C99中,結(jié)構(gòu)體中的最后一個(gè)元素是未知大小的數(shù)組,被稱為柔性數(shù)組成員。
特點(diǎn)
1.結(jié)構(gòu)體中柔性數(shù)組成員前必須至少有一個(gè)其他成員。
2.sizeof返回的這種結(jié)構(gòu)體的大小不包括柔性數(shù)組的內(nèi)存大小。
3.包含柔性數(shù)組成員的結(jié)構(gòu)體用malloc函數(shù)進(jìn)行內(nèi)存動(dòng)態(tài)內(nèi)存的動(dòng)態(tài)分配,并且分配的內(nèi)存應(yīng)大于結(jié)構(gòu)體的大小,以適應(yīng)柔性數(shù)組的預(yù)期大小。
優(yōu)勢(shì)
1.方便內(nèi)存釋放。
2.利于訪問(wèn)速度,減少內(nèi)存碎片。
#include<stdio.h>
#include<stdlib.h>
struct S
{
int n;
int arr[];
};
int main()
{
struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
//給arr分配內(nèi)存20個(gè)字節(jié)的空間
if (ps == NULL)
{
return 1;
}
//……………………操作
free(ps);
ps = NULL;
return 0;
}到此這篇關(guān)于C語(yǔ)言深入講解動(dòng)態(tài)內(nèi)存分配函數(shù)的使用的文章就介紹到這了,更多相關(guān)C語(yǔ)言動(dòng)態(tài)內(nèi)存分配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語(yǔ)言動(dòng)態(tài)內(nèi)存分配和內(nèi)存操作函數(shù)使用詳解
- C語(yǔ)言動(dòng)態(tài)內(nèi)存的分配最全面分析
- 深入了解C語(yǔ)言中的動(dòng)態(tài)內(nèi)存分配
- C語(yǔ)言動(dòng)態(tài)內(nèi)存的分配實(shí)例詳解
- c語(yǔ)言詳解動(dòng)態(tài)內(nèi)存分配及常見錯(cuò)誤的解決
- C語(yǔ)言深入探索動(dòng)態(tài)內(nèi)存分配的使用
- C語(yǔ)言的動(dòng)態(tài)內(nèi)存分配及動(dòng)態(tài)內(nèi)存分配函數(shù)詳解
- C語(yǔ)言動(dòng)態(tài)內(nèi)存分配圖文講解
相關(guān)文章
c語(yǔ)言中回調(diào)函數(shù)的使用以及實(shí)際作用詳析
回調(diào)函數(shù)就是一個(gè)通過(guò)函數(shù)指針調(diào)用的函數(shù),如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用其所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù),這篇文章主要給大家介紹了關(guān)于c語(yǔ)言中回調(diào)函數(shù)的使用以及實(shí)際作用的相關(guān)資料,需要的朋友可以參考下2021-07-07
C++實(shí)現(xiàn)高并發(fā)異步定時(shí)器
這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)高并發(fā)異步定時(shí)器,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11
基于Qt實(shí)現(xiàn)系統(tǒng)主題感知功能
在現(xiàn)代桌面應(yīng)用程序開發(fā)中,系統(tǒng)主題感知是一項(xiàng)重要的功能,它使得應(yīng)用程序能夠根據(jù)用戶的系統(tǒng)主題設(shè)置(如深色模式或淺色模式)自動(dòng)調(diào)整其外觀,Qt 作為一個(gè)跨平臺(tái)的C++圖形用戶界面應(yīng)用程序開發(fā)框架,提供了豐富的工具和類來(lái)實(shí)現(xiàn)這一功能,需要的朋友可以參考下2024-12-12
C++中std::partial_sort的使用小結(jié)
std::partial_sort?是?C++?標(biāo)準(zhǔn)庫(kù)中的一個(gè)算法,它可以對(duì)容器中的一部分元素進(jìn)行排序,本文主要介紹了C++中std::partial_sort的使用小結(jié),感興趣的可以了解一下2025-04-04
C語(yǔ)言字符串函數(shù),字符函數(shù),內(nèi)存函數(shù)使用及模擬實(shí)現(xiàn)
這篇文章主要介紹了C語(yǔ)言字符串函數(shù),字符函數(shù),內(nèi)存函數(shù)使用及模擬實(shí)現(xiàn),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
Qt中QSettings配置文件的讀寫和應(yīng)用場(chǎng)景詳解
這篇文章主要給大家介紹了關(guān)于Qt中QSettings配置文件的讀寫和應(yīng)用場(chǎng)景的相關(guān)資料,QSettings能讀寫配置文件,當(dāng)配置文件不存在時(shí),可生成配置文件,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
詳解C++中的指針結(jié)構(gòu)體數(shù)組以及指向結(jié)構(gòu)體變量的指針
這篇文章主要介紹了C++中的指針結(jié)構(gòu)體數(shù)組以及指向結(jié)構(gòu)體變量的指針的用法,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09

