我是動態和靜態分配的新手,我注意到一個奇怪的行為。我做了以下代碼片段:
#include ...
int main(void){
int i ;
printf(" using amesand :%p\n", &i);
int *j = malloc(sizeof(*j)) ;
printf(" using malloc :%p\n", j)
}
然后編譯并生成:
using amesand :0x7ffc0128695c
using malloc :0x6686b0
我在某處讀到過
所有指標在同一實作中具有相同的寬度。
有人可以解釋為什么 malloc() 回傳的指標只有3 個位元組長嗎?
uj5u.com熱心網友回復:
使用sizeof運算子來確定指標的寬度,例如:
int i;
printf(" using amesand :%zu\n", sizeof( &i ));
int *j = malloc(sizeof(*j));
printf(" using malloc :%zu\n", sizeof( j) );
對于此輸出,地址可以具有不同的值,具體取決于分配相應記憶體的位置。并且使用轉換說明符%p通常會生成(如您的情況)一個跳過前導零的輸出。
uj5u.com熱心網友回復:
所有指標在同一實作中具有相同的寬度。
是的,至少嚴格遵守 C 程式。有一些常見的非標準擴展,其中較大的指標與普通指標混合在一起,通常與非標準關鍵字far。
然而,這不是這里的問題,而只是您使用printf. 默認情況下,它會洗掉前導零。不僅適用于十六進制,也適用于任何數字。printf("%d", 1)列印1對嗎?而且不0000000001只是因為int正好是4個位元組= 10個十進制數字。指標和十六進制沒有什么不同,默認情況下會洗掉前導零,直到您告訴函式否則。
如果你想列印一個與指標大小相對應的十六進制數,你可以使用%.16p16 位 = 8 位元組的大指標。或者可變/可移植,像這樣:
printf(" using malloc :%.*p\n", sizeof(j)*2, j);
更正了在 x86_64 Linux 上測驗的示例:
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i ;
printf(" using amesand:\t%.*p\n", sizeof(&i)*2, &i);
int *j = malloc(sizeof(*j)) ;
printf(" using malloc:\t%.*p\n", sizeof(j)*2, j);
}
輸出:
using amesand: 0x00007ffe8710871c
using malloc: 0x0000000000ed82b0
關于為什么不同的記憶體型別有不同的地址,看這個:
A program using different region of memory for static objects, automatic objects, and dynamic allocation objects
uj5u.com熱心網友回復:
使用%p,您的 C 實作只是省略了指標值的前導零。
列印“0x6686b0”并不表示指標是三個位元組長;它僅僅表示此值為6686b0 16,其等于006686b0 16,00000000006686b0 16,或0000000000000000000000000000000006686b0 16。前導零已被省略。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/315006.html
上一篇:選擇排序中動態陣列和指標的問題
