一個結構體指針數組內存分配問題引發的思考


為了在程序運行過程中,將兩個結構體數組合並成一個大的結構體,在節省空間的基礎上,我使用一個大的結構體指針數組,來將其元素分別指向結構體數組中的結構體。

實現過程中,發現這個結構體指針數組的大小是不能確定的,所以使用變長數組來聲明,由於gcc編譯器未支持C99標准,所以編譯無法通過。

進而,我使用malloc來在運行過程中分配內存。具體代碼思想如下:

int i,j,m,n;
    scanf("%d%d",&m,&n);
    int **a;
    a=(int**)malloc(sizeof(int*)*m);
    for(i=0;i<m;++i)
    a[i]=(int *)malloc(sizeof(int)*n);

上述代碼,使用二維指針,來實現指針數組的空間分配。接下來再使用一級指針指向不同的內存空間。

任務完成。

任何存儲空間,均可以通過malloc函數生成。指針數組也不例外。

以下是一個生成10個char*型的指針數組的代碼,要存儲char*型的數組,其數組名,即指針類型,必須為char**型。

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


這里需要注意兩個地方:

1.指針的強制轉換。

malloc的返回值為void*型,所以在賦值給char**型時,要強制轉換為目標類型。部分編譯器對此檢查不嚴格,但為了可移植性,還是加上強制轉換為好。

2.malloc參數的確定。

malloc參數值為申請內存空間的大小,每個char *型的空間為sizeof(char *), 10個空間就再乘10。

一般來說,無論是何種類型TYPE,在申請時均可以寫作

TYPE * p = (TYPE*)malloc(sizeof(TYPE) * N);

我突然想到之前的一篇文章,二級指針加減與一級指針加減的區別,連接如下:

https://www.cnblogs.com/zzdbullet/p/9493369.html

進而,回顧

數組指針與指針數組

數組指針(也稱行指針)

定義 int (*p)[n];

()優先級高,首先說明p是一個指針,指向一個整型的一維數組,這個一維數組的長度是n,也可以說是p的步長。也就是說執行p+1時,p要跨過n個整型數據的長度。

如要將二維數組賦給一指針,應這樣賦值:

int a[3][4];

int (*p)[4]; //該語句是定義一個數組指針,指向含4個元素的一維數組。

p=a;        //將該二維數組的首地址賦給p,也就是a[0]或&a[0][0]

p++;       //該語句執行過后,也就是p=p+1;p跨過行a[0][]指向了行a[1][]

所以數組指針也稱指向一維數組的指針,亦稱行指針。

指針數組

定義 int *p[n];

[]優先級高,先與p結合成為一個數組,再由int*說明這是一個整型指針數組,它有n個指針類型的數組元素。

這里執行p+1時,則p指向下一個數組元素,這樣賦值是錯誤的:p=a;因為p是個不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它們分別是指針變量可以用來存放變量地址。

但可以這樣 *p=a; 這里*p表示指針數組第一個元素的值,a的首地址的值。

如要將二維數組賦給一指針數組:

int *p[3];
int a[3][4]; p++; //該語句表示p數組指向下一個數組元素。注:此數組每一個元素都是一個指針
for(i=0;i<3;i++)
p[i]=a[i] //這里int *p[3] 表示一個一維數組內存放着三個指針變量,分別是p[0]、p[1]、p[2]

所以要分別賦值。

數組指針只是一個指針變量,似乎是C語言里專門用來指向二維數組的,它占有內存中一個指針的存儲空間。

指針數組是多個指針變量,以數組形式存在內存當中,占有多個指針的存儲空間。

還需要說明的一點就是,同時用來指向二維數組時,其引用和用數組名引用都是一樣的。

比如要表示數組中i行j列一個元素:

*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]

//優先級:()>[]>*

指針數組和數組指針的內存布局

指針數組:首先它是一個數組,數組的元素都是指針,數組占多少個字節由數組本身的大小決定,每一個元素都是一個指針,在32 位系統下任何類型的指針永遠是占4 個字節。它是“儲存指針的數組”的簡稱。

數組指針:首先它是一個指針,它指向一個數組。在32 位系統下任何類型的指針永遠是占4 個字節,至於它指向的數組占多少字節,不知道,具體要看數組大小。它是“指向數組的指針”的簡稱。


考慮

int *p1[10];

int (*p2)[10];


“[]”的優先級比“*”要高。p1 先與“[]”結合,構成一個數組的定義,數組名為p1,int *修飾的是數組的內容,即數組的每個元素。那現在我們清楚,這是一個數組,其包含10 個指向int 類型數據的指針,即指針數組。至於p2 就更好理解了,在這里“()”的優先級比“[]”高,“*”號和p2 構成一個指針的定義,指針變量名為p2,int 修飾的是數組的內容,即數組的每個元素。數組在這里並沒有名字,是個匿名數組。那現在我們清楚p2 是一個指針,它指向一個包含10 個int 類型數據的數組,即數組指針。

 
參考:
https://zhidao.baidu.com/question/502973775.html
https://blog.csdn.net/qq_40828914/article/details/78506281
http://www.cnblogs.com/dragondove/p/6387682.html
https://www.cnblogs.com/mq0036/p/3382732.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM