![](/img/trans.png)
[英]malloc(sizeof(struct element) * size); or malloc(sizeof(struct element) * 1);
[英]Are “malloc(sizeof(struct a *))” and “malloc(sizeof(struct a))” the same?
這個問題是Malloc調用崩潰的延續,但在其他地方有效
我嘗試了以下程序,我發現它工作(即沒有崩潰 - 這也在上面提到的鏈接中提到)。 我很幸運能讓它工作但是我正在尋找SO專家對於它為什么有效的合理解釋?!
以下是使用malloc()
wrt structures
和pointers
分配memory
一些基本知識
malloc(sizeof(struct a) * n)
分配n
個類型struct a
元素。 並且,可以使用pointer-to-type-"struct a"
的pointer-to-type-"struct a"
來存儲和訪問該存儲器位置。 基本上是一個struct a *
。 malloc(sizeof(struct a *) * n)
分配n
個類型struct a *
元素。 然后,每個元素都可以指向struct a
類型的元素。 基本上malloc(sizeof(struct a *) * n)
分配一個array(n-elements)-of-pointers-to-type-"struct a"
。 並且,可以使用pointer-to-(pointer-to-"struct a")
來存儲和訪問所分配的存儲器位置。 基本上是一個struct a **
。 所以當我們創建一個array(n-elements)-of-pointers-to-type-"struct a"
,就是這樣
struct a *
而不是struct a **
? array(n-elements)-of-pointers-to-type-"struct a"
使用pointer-to-"struct a"
? data * array = NULL;
if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
代碼段如下:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
typedef struct {
int value1;
int value2;
}data;
int n = 1000;
int i;
int val=0;
data * array = NULL;
if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
printf("unable to allocate memory \n");
return -1;
}
printf("allocation successful\n");
for (i=0 ; i<n ; i++) {
array[i].value1 = val++;
array[i].value2 = val++;
}
for (i=0 ; i<n ; i++) {
printf("%3d %3d %3d\n", i, array[i].value1, array[i].value2);
}
free(array);
printf("freeing successful\n");
return 0;
}
編輯:好的,如果我錯誤地執行了以下操作
data * array = NULL;
if ((array = (data *)malloc(sizeof(data *) * n)) == NULL) {
有沒有辦法捕獲(在使用任何GCC
標志的編譯時)這些無意識的編程錯字,它可能有時會工作,並可能隨時爆發! 我用-Wall
編譯了這個,發現沒有警告!
沒有。
sizeof(struct a*)
是指針的大小。
sizeof(struct a)
是整個struct的大小。
似乎存在一個根本性的誤解。
malloc(sizeof(struct a)* n)分配n個類型struct a元素。
不,這就是人們通常在這樣的電話之后使用它的原因。 malloc(size)
分配size
bytes的內存區域。 你對該地區的所作所為完全取決於你。 唯一重要的是你不要超越分配內存的限制。 假設4個字節的float
和int
以及8個字節的double
,在成功的malloc(100*sizeof(float));
,您可以使用400字節中的前120個作為15個double
s的數組,接下來的120作為30個float
的數組,然后在其后面放置一個20個char
的數組,並用35填充剩余的140個字節int
如果你想秒。 這是完全無害的定義行為。
malloc
返回一個void*
,它可以隱式地轉換為任何類型的指針,所以
some_type **array = malloc(100 * sizeof(data *)); // intentionally unrelated types
非常好,它可能不是你想要的記憶量。 在這種情況下很可能是因為指針往往具有相同的大小,而不管它們指向的是什么。
更容易給你錯誤的內存量
data *array = malloc(n * sizeof(data*));
就像你擁有它一樣。 如果將分配的內存塊用作n
data
類型元素的數組,則有三種可能性
sizeof(data) < sizeof(data*)
。 那你唯一的問題是你在浪費一些空間。 sizeof(data) == sizeof(data*)
。 一切都很好,沒有浪費空間,好像你根本沒有打字錯誤。 sizeof(data) > sizeof(data*)
。 然后,您將訪問在觸摸稍后的數組元素時不應訪問的內存,這是未定義的行為。 根據各種各樣的事情,可以始終如一地工作,好像你的代碼是正確的,立即崩潰與段錯誤或介於兩者之間的任何東西(從技術上講,它可能表現得不能有意義地放在這兩者之間,但這將是不尋常的)。 如果你有意這樣做,知道點1或2.適用,這是不好的做法,但不是錯誤。 如果你無意中這樣做,那么無論哪個點適用都是錯誤的,無害但很難找到1.或2.適用,有害但通常在3的情況下更容易檢測。
在你的例子中。 data
是4分。 8個字節(可能),在64位系統上將它們放入1. resp。 2.概率很高,在32位系統上分為2分。 3。
避免此類錯誤的推薦方法是
type *pointer = malloc(num_elems * sizeof(*pointer));
這個array = (data *)malloc(sizeof(data *) * n)
為struct data
分配sizeof(data*)
( 指針 ),如果你想這樣做,你需要一個你的array
作為data** array
。
在您的情況下,您希望指針指向sizeof(data)
,內存中的結構,而不是指向另一個指針。 這將需要data**
(指向指針的指針)。
將它賦給struct a *而不是struct a **是否有效?
好吧,從技術上講,這樣分配是有效的,但取消引用這樣的指針是錯誤的(UB)。 你不想這樣做。
有效訪問/取消引用已分配的數組(n元素)-of-pointers-to-type-“struct a”使用指針到“struct a”?
不,未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.