[英]Are “malloc(sizeof(struct a *))” and “malloc(sizeof(struct a))” the same?
[英]Is the sizeof operator needed for malloc?
在這個程序(C,而不是C ++)中 ,為什么無論使用sizeof運算符,malloc總是返回正確的大小?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *c = malloc(3);
short *s = malloc(3); /* or malloc(3 * sizeof(short))? */
int *i = malloc(3); /* or malloc(3 * sizeof(int))? */
long *l = malloc(3); /* or malloc(3 * sizeof(long))? */
printf("%p\n", c++);
printf("%p\n", c++);
printf("%p\n", c++);
printf("---\n");
printf("%p\n", s++);
printf("%p\n", s++);
printf("%p\n", s++);
printf("---\n");
printf("%p\n", i++);
printf("%p\n", i++);
printf("%p\n", i++);
printf("---\n");
printf("%p\n", l++);
printf("%p\n", l++);
printf("%p\n", l++);
return 0;
}
輸出是:
0x1e82010 (1 byte)
0x1e82011
0x1e82012
---
0x1e82030 (2 bytes)
0x1e82032
0x1e82034
---
0x1e82050 (4 bytes)
0x1e82054
0x1e82058
---
0x1e82070 (8 bytes)
0x1e82078
0x1e82080
我錯過了什么嗎?
4.0.4-303.fc22.x86_64 clang版本3.5.0(標簽/ RELEASE_350 / final)目標:x86_64-redhat-linux-gnu線程模型:posix
long *l = malloc(3);
這分配(或者更確切地說是嘗試分配)3 個字節 。
通常, malloc()
實際上會分配比您請求更多的內容,用於對齊和簿記。 因此,在調用malloc(3)
,您可能能夠在分配的內存中存儲3個long
值。 但它不能保證。
是的,你確實需要sizeof
。
寫這個的最好方法是:
long *l = malloc(3 * sizeof *l);
通過使用指針所指向的大小( sizeof *l
),您不必long
兩次指定類型,如果類型稍后更改,代碼將不會中斷。
更好的是:
long *l = malloc(3 * sizeof *l);
if (l == NULL) {
/* malloc failed, recover or bail out */
}
如果您願意,可以將其寫成:
long *l = malloc(3 * sizeof(*l));
但額外的括號不是必需的,size sizeof
是一元運算符,而不是函數。
printf("%p\n", l++);
printf("%p\n", l++);
printf("%p\n", l++);
遞增指針會使其指向的類型大小。 long
顯然是你系統上的8個字節,所以這將使l
至少增加24個字節,遠遠超過你從malloc
請求的3個字節。 結果是未定義的行為。
通過遞增l
,你已經丟失了malloc
返回的原始值; 是時候打電話給free()
。
最后, %p
格式說明符需要類型為void*
的參數。 傳遞不同的指針類型很可能“工作”,但你真的應該將它轉換為void*
:
printf("%p\n", (void*)l++);
我錯過了什么嗎?
是的,你完全忽略了這一點。
您正在測試指針算術 ,它是根據指向類型的大小定義的。 這與malloc()
分配的malloc()
量完全無關,甚至與所討論的指針完全指向有效地址無關。
遞增指針會使存儲的地址增加基本類型的大小。 它不依賴於指針指向的內容。
遞增指針時遞增的字節數僅基於其類型 - 例如,如果將int*
遞增1,則將地址遞增4個字節。 這與malloc
或sizeof
或任何東西無關。
您會發現,如果您開始在這些指針中存儲值,您將遇到奇怪的行為,因為您沒有分配足夠的空間來存儲3個short
s,3個int
或3個long
。
你已成為謬誤的犧牲品。 您沒有分析malloc返回的內容,您看到增量知道如何根據變量類型的大小正確遞增指針。 沒有關於malloc調用的信息告訴你實際分配了多少RAM。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.