簡體   English   中英

malloc需要sizeof運算符嗎?

[英]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個字節。 這與mallocsizeof或任何東西無關。

您會發現,如果您開始在這些指針中存儲值,您將遇到奇怪的行為,因為您沒有分配足夠的空間來存儲3個short s,3個int或3個long

你已成為謬誤的犧牲品。 您沒有分析malloc返回的內容,您看到增量知道如何根據變量類型的大小正確遞增指針。 沒有關於malloc調用的信息告訴你實際分配了多少RAM。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM