溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C語(yǔ)言動(dòng)態(tài)內(nèi)存分配函數(shù)如何使用

發(fā)布時(shí)間:2022-05-11 13:38:48 來(lái)源:億速云 閱讀:127 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“C語(yǔ)言動(dòng)態(tài)內(nèi)存分配函數(shù)如何使用”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“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指向的空間之后沒有足夠的內(nèi)存空間,則realloc函數(shù)會(huì)重新找一塊內(nèi)存空間,開辟一塊滿足需求的內(nèi)存空間,并且把原來(lái)內(nèi)存中的數(shù)據(jù)拷貝過來(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)開辟空間的越界訪問

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.利于訪問速度,減少內(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ù)如何使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI