我有一个关于使用intptr_tvs. 的问题long int.我观察到递增内存地址(例如通过手动指针算术)因数据类型而异.例如,递增char指针会将1添加到内存地址,而递增int指针会为double添加4,8,为long double添加16等等...
起初我做了这样的事情:
char myChar, *pChar;
float myFloat, *pFloat;
pChar = &myChar;
pFloat = &myFloat;
printf( "pChar: %d\n", ( int )pChar );
printf( "pFloat: %d\n", ( int )pFloat );
pChar++;
pFloat++;
printf( "and then after incrementing,:\n\n" );
printf( "pChar: %d\n", (int)pChar );
printf( "pFloat: %d\n", (int)pFloat );
Run Code Online (Sandbox Code Playgroud)
编译和执行得很好,但XCode给了我警告我的类型转换:"从指针转换为不同大小的整数."
经过一些谷歌搜索和binging(后者还是一个词?),我看到有些人推荐使用intptr_t:
#include <stdint.h>
Run Code Online (Sandbox Code Playgroud)
...
printf( "pChar: %ld\n", ( intptr_t )pChar );
printf( "pFloat: %ld\n", ( intptr_t )pFloat );
Run Code Online (Sandbox Code Playgroud)
这确实解决了错误.所以,我想,从现在开始,我应该使用intptr_t类型转换指针...但是经过一些烦躁之后,我发现我可以通过替换int为long …
使用intptr_t作为通用存储(保存指针和整数值)而不是void*?(如下所示:http://www.crystalspace3d.org/docs/online/manual/Api1_005f0-64_002dBit-Portability-Changes.html)
对于我已经读过的内容:
int- > void*- > int往返不保证保持原值; 我猜int- > intptr_t- > int会的void*和intptr_t要求铸件,所以没有在这里得到好处void*表示存储指针时的显式转换次数较少,intptr_t表示存储整数值时转换次数较少intptr_t 需要C99我还应该考虑什么呢?
鉴于我需要在结构中存储"泛型"指针的值并且对指向的内存本身没有兴趣,我发现将它存储为intptr_t比a 更为语义正确void*.问题是a uintptr_t是否更适合,并且当一个人更喜欢另一个人时?
让我先说一下,我所知道的是我要提出的是一个致命的罪,并且即使考虑它,我也可能会在编程地狱中燃烧.
也就是说,我仍然有兴趣知道为什么这不起作用.
情况是:我有一个我在任何地方使用的引用计数智能指针类.它目前看起来像这样(注意:不完整/简化的伪代码):
class IRefCountable
{
public:
IRefCountable() : _refCount(0) {}
virtual ~IRefCountable() {}
void Ref() {_refCount++;}
bool Unref() {return (--_refCount==0);}
private:
unsigned int _refCount;
};
class Ref
{
public:
Ref(IRefCountable * ptr, bool isObjectOnHeap) : _ptr(ptr), _isObjectOnHeap(isObjectOnHeap)
{
_ptr->Ref();
}
~Ref()
{
if ((_ptr->Unref())&&(_isObjectOnHeap)) delete _ptr;
}
private:
IRefCountable * _ptr;
bool _isObjectOnHeap;
};
Run Code Online (Sandbox Code Playgroud)
今天我注意到sizeof(Ref)= 16.但是,如果我删除布尔成员变量_isObjectOnHeap,则sizeof(Ref)减少到8.这意味着对于我的程序中的每个Ref,有7.875个浪费的RAM字节......并且我的程序中有很多很多Refs .
好吧,这似乎浪费了一些内存.但我真的需要那些额外的信息(好吧,幽默我,并为了我真正做的讨论而假设).我注意到,由于IRefCountable是一个非POD类,它(可能)总是被分配在一个字对齐的内存地址上.因此,(_ptr)的最低有效位应始终为零.
这让我想知道...有什么理由说我不能将我的一点布尔数据或指针的最低有效位,并因此将sizeof(Ref)减少一半而不牺牲任何功能?当然,在取消引用指针之前,我必须小心取出那个位,这会使指针解引用效率降低,但这可能是因为Refs现在更小,因此更多可以立即适应处理器的缓存,依此类推.
这是合理的事吗?还是我为自己创造了一个受伤的世界?如果是后者,那么伤害到底是怎么回事?(请注意,这是需要在所有合理的现代桌面环境中正确运行的代码,但它不需要在嵌入式计算机或超级计算机或任何异国情况下运行)
我读到64位机器实际上只使用48位地址(具体来说,我使用的是英特尔酷睿i7).
我希望额外的16位(位48-63)与地址无关,并将被忽略.但是当我尝试访问这样的地址时,我收到了一个信号EXC_BAD_ACCESS.
我的代码是:
int *p1 = &val;
int *p2 = (int *)((long)p1 | 1ll<<48);//set bit 48, which should be irrelevant
int v = *p2; //Here I receive a signal EXC_BAD_ACCESS.
Run Code Online (Sandbox Code Playgroud)
为什么会这样?有没有办法使用这16位?
这可用于构建更多缓存友好的链表.不是将8个字节用于下一个ptr,而是将8个字节用于密钥(由于对齐限制),可以将密钥嵌入到指针中.
V8如何在内存中存储整数?
例如整数5?
我知道它存储在堆中,但是它到底是如何存储的呢?诸如元数据和实际值本身之类的东西。int 存储之前是否添加了常量?
我在基于 x32 的处理器上,其中char = 1 byte, short = 2 bytes and int = 4 bytes.
当我创建一个char包含20元素的类型数组时,我希望看到分配给该数组的 20 个内存空间,其地址仅1 byte因数组类型而异。
如果我从数组中取出两个连续的元素并减去它们的地址,那么1在这种情况下我不应该得到吗?
对于类型为shortand的数组int,我希望得到2and 4。这是因为short和int元素需要在内存中对齐。short elements将在偶数地址(差异 2)上,int elements并将在可被 4 整除的地址上。
但是,当我运行以下代码时,怎么会得到1,1,1而不是1,2,4?
我怀疑在指针算术方面我遗漏了一些关键细节。
char vecc[20];
printf("%i\n", &vecc[1]-&vecc[0]);
short vecs[20];
printf("%i\n", &vecs[1]-&vecs[0]);
int veci[20];
printf("%i\n", &veci[1]-&veci[0]);
Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <string>
#include <cmath>
using namespace std;
int main() {
int a = 5;
int b = &a;
}
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?如果我像这样制作 ba 指针int *b = &a,那会起作用,但如果内存地址只是一个十六进制整数,那么为什么这不行?
c ×4
pointers ×4
c++ ×3
intptr ×2
32bit-64bit ×1
64-bit ×1
arrays ×1
casting ×1
javascript ×1
memory ×1
standards ×1
subtraction ×1
types ×1
v8 ×1
x86-64 ×1