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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数组内存分配概念

發布時間:2023/12/18 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数组内存分配概念 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在這里解答一下:

int arr[4];

&arr[1] = arr[0] + sizeof(int) ;


靜態分配, 即普通數組, 由于在棧中分配, 而棧的生成方向是自高地址向低地址生成。 所以有:

&arr[0] > &arr[1] ....

動態分配的數組。針對動態數組。 動態數組的內存分配在heap中。 而heap 的生成是由低地址向高地址生成。 所以有:

&arr[0] < &arr[1] <...

這是我以為的。 ?答案是我我錯了。

測試一下:

[cpp] view plain copy print?
  • #include?<iostream>??
  • ??
  • ??
  • using?namespace?std;??
  • ??
  • ??
  • ??
  • ??
  • int?main()?{??
  • ???int?n?=?4;??
  • ???int?*ptr?=?new?int[n];??
  • ??
  • ??
  • ???//?dynamic?array:?on?heap??
  • ???????cout?<<?"dynamic?array:?"?<<?endl;??
  • ???for(int?i?=?0;?i?<?4;?++i)?{??
  • ???????cout?<<?&ptr[i]?<<?endl;??
  • ???}??
  • ??
  • ??
  • ???//?ordinary?array:?on?stack??
  • ???int?arr[4];??
  • ???cout?<<?"ordinary?array:?"?<<?endl;??
  • ???for(int?i?=?0;?i?<?4;?++i)?{??
  • ???????cout?<<?&arr[i]?<<?endl;??
  • ???}??
  • ???return?0;??
  • }??
  • #include <iostream>using namespace std;int main() {int n = 4;int *ptr = new int[n];// dynamic array: on heapcout << "dynamic array: " << endl;for(int i = 0; i < 4; ++i) {cout << &ptr[i] << endl;}// ordinary array: on stackint arr[4];cout << "ordinary array: " << endl;for(int i = 0; i < 4; ++i) {cout << &arr[i] << endl;}return 0; }
    結果如下:



    為什么無論是靜態數組還是動態數組, 數組元素的分配都是對元素從低地址到高地址。?

    無論動態還是靜態?地址都是arr[0]?<?arr[1]?也就是數組內存是統一分配的
    內部元素都是從低地址到高地址 。?
    ? ? ? ? ?

    1、內存分配的三種方式:

    1)、從靜態存儲區分配。數據的內存在程序編譯時已經被分配,該內存在整個運行期間長期駐留,不會被釋放;程序結束時,由操作系統自動釋放。這類數據包括靜態數據和全局數據。

    2)、從棧空間分配。函數執行過程中,函數中的局部變量的內存,在棧上被分配;當函數調用完成后,隨函數的返回空間也被釋放。

    3)、從堆空間分配。由開發者動態的申請內存,并手動的釋放內存。

    本文具體介紹動態內存分配,C語言中采用malloc、recalloc等函數分配內存;c++中使用new操作符申請內存。

    malloc函數的返回值為void*,調用該函數時,需要顯式的類型轉化。返回值表示內存空間的首地址。如果該地址為NULL,表示系統沒有滿足的內存可供分配。因此在使用該地址之前,必須判斷是否分配成功。例如:

    int*p=(int*)malloc(sizeof(int)*10);

    if(p != NULL)

    {

    ......//使用該內存空間

    }

    在該內存使用完成后,需要開發者手動釋放該內存:free(p):

    這里需要注意:1)、調用free后,p和所指向的內存地址被斷開,但是p的值仍然沒有變化,此時如果調用p,將會出現錯誤,這時p就是一個野指針;因此當free(p);之后,應該將p的值賦為NULL,以免p再次調用出現錯誤。2)、雖然內存已經分配完成,但是并沒有初始化,直接使用,取到的結果不正確。

    4)、當malloc申請的內存不滿足用戶使用要求時,就需要重新分配內存,這時可以使用realloc函數。

    void *realloc(void *memblock,size_t size ); memblock參數表示已經分配的內存地址的指針,即就是p;

    size參數表示需要分配的字節數

    該函數的返回值為,重新分配的內存空間的首地址。

    realloc函數,在malloc函數已經分配的內存基礎上再次擴充內存。realloc函數的返回值類型仍為void*。可以分三種情況來解釋realloc。

    情況一:需要分配的內存空間小于已經分配的空間。

    那么這時只是從原來已經分配的內存空間中,將多余的空間釋放,保留realloc函數需要的空間大小,將原來空間的的首地址賦值給realloc函數返回(這個地址和p的值是相同的);如果這樣做的,可能會導致數據出錯,因此一般不要縮小原內存空間;

    情況二:需要分配的內存空間等于已經分配的空間。

    將原來內存空間的首地址賦值給realloc函數返回;

    情況三:需要分配的內存空間大于已經分配的空間。

    1)如果原來的內存后,還有足夠的空間,滿足分配要求,那么直接在原來的內存的后面,分配適量的空間,并將原來空間的首地址賦值給realloc函數,返回;

    2)如果原來內存后,沒有足量的內存空間,滿足分配要求,那么重新選擇一塊足量的空間分配,并將原來已經分配的空間的數據拷貝到新分配的內存中,將原指針p指向的空間釋放。將新分配的空間首地址賦值給realloc函數返回,因此對于原來的空間,realloc函數在分配內存時,已經釋放了原來的內存,不需要再次釋放,否則會出錯。

    情況四:當分配的內存大小為0

    系統是可以返回一個非NULL值,但是這個空間不能被使用。使用將會出錯,效果等同于free(p);

    情況五:當原來的指針為NULL

    這種情況,的作用就相當于直接調用malloc函數一樣;可以這樣理解,NULL說明原空間沒有分配成功,那么調用realloc函數,肯定需要分配一塊新的內存空間,這不就相當于直接調用了malloc函數。

    情況六:如果realloc函數調用失敗

    那么原來的空間地址不會被釋放,保留原來的內存,該內存空間可以正常使用。


    綜上,在使用malloc函數時,需要注意幾點:1)調用malloc函數后,需要判斷內存是否分配成功;2)使用空間之前,需要給空間賦初始值;3)防止內存越界訪問;4)釋放內存空間之后free(p);,需要將原指針的值賦空(p=null;),以防再次使用產生錯誤,出現野指針;5)realloc函數對于原始的內存空間,在分配內存時已經做過處理,因此除realloc函數調用失敗外,其余情況不能再次釋放原空間內存,否則會出錯。


    2、既然malloc和free已經可以分配內存了,為什么還要引入new和delete?

    首先需要明白,malloc和free是c語言中的c庫函數,而new和delete是c++中的標識符;因此這兩組擁有不同的性質;

    接著,malloc和free不僅可以使用在C語言中,也可以使用在c++語言中,但是new和delete只是c++中特有的屬性,在C語言中無法使用,因此new和delete有他的局限性;

    再次,new和delete不僅需要分配內存空間,而且在面向對象的語言中,對于對象,還需要完成初始化,觸發對象的構造和析構,這些操作是malloc和free無法完成的(筆者就在曾經實現鏈表的過程中,在結構體定義時,將一個數組元素定義為string類型的,在使用malloc申請內存后,調用過程中無法給該元素賦值。從這個例子中可以看出雖然malloc和new分配的內存大小相等,但是具體的內存內部工作還是有區別的)。

    最后,malloc在分配內存時,需要開發者手動的指定元素的大小,并且返回值需要顯式的類型轉化;但是new就不需要指定和轉化。


    3、在c++中,既然new和delete可以完成所有分配的工作,為什么還要保留malloc和free?

    這是因為c++編譯器為了兼容c編譯,是c中的所有函數可以在c++編譯器上正常使用,因此保留了malloc和free

    總結

    以上是生活随笔為你收集整理的数组内存分配概念的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。