[英]How are Java generics different from C++ templates? Why can't I use int as a parameter?
[英]Why can't I access int with different pointer in C++?
我希望能夠使用p指針訪問值。 但是當我使用p指針時,我總是得到b變量等於零。 請參考下面的代碼片段。
basepointer = malloc(512);
*((int*)basepointer+32) = 455; // putting int value in memory
void *p = basepointer + 32; // creating other pointer
int a,b;
a = *((int*)basepointer+32); // 455, retrieving value using basepointer
b = *((int*)p); // 0, retrieving value using p
為什么會這樣呢? 如何使用p指針訪問值?
我找不到一個很好的重復答案,所以這是怎么回事:
指針算術始終以指針的基本類型為單位進行。 也就是說,當您擁有T *ptr
(指向某種類型T
的指針)時, ptr + 1
不是內存中的下一個字節,而是下一個T
換句話說,您可以想象一個指針,就像數組和索引的組合:
T *ptr;
T array[/*some size*/];
ptr = &array[n];
如果ptr
是指向array[n]
(第n個元素)的指針,則ptr + i
是指向array[n + i]
(第(n + i)個元素)的指針。
讓我們看一下您的代碼:
*((int*)basepointer+32) = 455;
在這里,您將基basepointer
為(int*)
,然后將其添加32
。 這為您提供了basepointer
之后的第32個int
的地址。 如果您的平台使用4字節整數,則實際偏移量為32 * 4 = 128
字節。 這是我們存儲455
。
那你做
void *p = basepointer + 32;
從技術上講,這是無效的代碼,因為basepointer
是void *
,並且因為void
沒有大小,所以您不能對void
進行算術運算。 作為擴展,gcc支持這一點,並假裝void
大小為1
。 (但是,您實際上不應該依賴於此:如果您要按字節尋址,則強制轉換為unsigned char *
。)
現在p
在basepointer
之后偏移32
。
a = *((int*)basepointer+32);
這從上面重復指針算法,並從int
偏移量32(即字節偏移量128
)中檢索值,該值仍為455
。
b = *((int*)p);
這將檢索存儲在字節偏移量32
處的int
值(在此示例中,它對應於int
偏移量8
)。 我們從未在此處存儲任何內容,因此b
本質上是垃圾(在您的平台上恰好是0
)。
使此代碼按預期工作的最小更改可能是
void *p = (int *)basepointer + 32; // use int-wise arithmetic to compute p
空指針算法在C / C ++中是非法的,GCC允許將其作為擴展。
您需要修改以下行:
void *p = basepointer + 32;
至
void *p = basepointer + 32 * sizeof(int);
因為指針算術是相對於類型大小而計算的。
例如:
如果sizeof (int) = 4
並且sizeof(short) = 2
並且int *p
地址為3000
short *sp
地址為4000
然后p + 3 = p + 3 * sizeof(int) = 3012
並且sp + 3 = sp + 3 *sizeof(short) = 4006
對於void,如果編譯器允許,則為1
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.