這篇文章主要介紹“C語言動態內存分配函數如何使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“C語言動態內存分配函數如何使用”文章能幫助大家解決問題。
局部變量和函數的形參向棧區申請空間
全局變量和static靜態變量向靜態區申請空間
動態內存分配向堆區申請空間(位于<stdlib.h>或<cstdlib>頭文件)
void* malloc (size_t size);
分配內存塊
分配一個連續可用的字節內存塊,返回指向該內存塊開頭的指針。
新分配的內存塊的內容未初始化,內存塊中的數據為不確定值。
如果為參數為零,則返回值取決于特定的庫實現(它可能是空指針,也可能不是空指針)。
參數
內存塊的大小,以字節為單位。
是無符號整數類型,size_t。
返回值
成功時,為指向函數分配的內存塊的指針。
此指針的類型始終為void*,可以將其轉換為所需的數據指針類型。(C++由于其類型檢查更為嚴格,則必須進行強制類型轉換)
如果函數未能分配請求的內存塊,則返回空指針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.斷開指針與動態開辟的空間的聯系,避免指針的危險操作
2.防止對同一塊動態空間內存空間的重復釋放
*/
return 0;
}輸出
0 1 2 3 4 5 6 7 8 9
void free(void* ptr);
解除分配內存塊
1.若參數ptr指向的空間不是動態開辟的,那么free函數的行為是未定義的。
2.若參數ptr是NULL指針,則free函數什么也不做。
3.free只釋放堆區空間,但ptr仍指向那塊空間。所以使用完free后要將ptr置為NULL,切斷ptr與該內存塊的聯系。
參數
指向要釋放的那塊空間的指針(必須指向初始位置)
返回值
無
錯誤案例
#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++));//這里指針移動
}
free(p);//導致free釋放的不是初始位置的指針,程序崩潰
p = NULL;
return 0;
}void* calloc(size_t num,size_t num);
分配和零初始化內存塊
1.函數的功能是為num個大小為size的元素開辟空間。
2.與malloc的區別只在于calloc會在返回地址前將申請的空間的每個字母初始化為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;
}void* realloc(void* ptr,size_t size);
重新分配內存塊
1.ptr為要調整的內存空間,size為調整后的新大小
2.返回值為調整后的內存塊的起始位置
注意事項
1.若ptr指向的空間之后有足夠的空間可以追加,則直接追加,然后返回ptr。
2.若ptr指向的空間之后沒有足夠的內存空間,則realloc函數會重新找一塊內存空間,開辟一塊滿足需求的內存空間,并且把原來內存中的數據拷貝過來,釋放舊的內存空間,最后返回新開辟的內存空間的地址。
#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;
}1.對NULL指針的解引用操作(要進行返回值的判斷)
2.對動態開辟空間的越界訪問
3.對非動態開辟內存的空間的使用free進行釋放
4.使用free釋放一塊動態開辟內存的一部分
(若指針位置發生變化,歸位后再進行釋放)
5.對同一塊動態內存的多次釋放
6.動態開辟內存忘記釋放(內存泄漏)
C99中,結構體中的最后一個元素是未知大小的數組,被稱為柔性數組成員。
特點
1.結構體中柔性數組成員前必須至少有一個其他成員。
2.sizeof返回的這種結構體的大小不包括柔性數組的內存大小。
3.包含柔性數組成員的結構體用malloc函數進行內存動態內存的動態分配,并且分配的內存應大于結構體的大小,以適應柔性數組的預期大小。
優勢
1.方便內存釋放。
2.利于訪問速度,減少內存碎片。
#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分配內存20個字節的空間
if (ps == NULL)
{
return 1;
}
//……………………操作
free(ps);
ps = NULL;
return 0;
}關于“C語言動態內存分配函數如何使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。