由于某些特殊原因,我需要获得指针的长度(字符)。 如果指针是:
0x2ADF4
它应该返回5
,
因为指针中有5个字符。
实际上我希望指针的十六进制表示的长度被转换为整数。
这个数字应该从指针到指针不等。
请注意我不希望总内存占用我的指针(我可以通过sizeoff获得)。
答案 0 :(得分:4)
您可以将ptr转换为intptr_t
类型,然后使用标准数字计数算法:
int main() {
int counter = 0;
int* ptr = &counter;
intptr_t val = (intptr_t)ptr;
while ( val > 0 )
{
val/=16;
++counter;
}
printf("%d", counter);
return 0;
}
答案 1 :(得分:4)
所以你想要你的指针的一些文本表示的长度(谨防术语,你不希望分配的内存区域的大小持有该指针),通常是指针的指针一些virtual address space内存位置(但可能不是)。
您应该注意到sprintf
and snprintf
都返回写入某个缓冲区的字节数(包括终止零字节),并且它们都接受NULL
缓冲区,因此您可以编码:
int ptrtextlen = sprintf(NULL, "%p", ptr);
在你的情况下(ptr
为0x2ADF4),它将返回8(因为0x2ADF4
需要7个字节,从0
开始,x
需要4
},以及一个额外的终止零字节)。顺便说一句,请阅读有关sprintf
的更多信息(您可以使用它来获取一些前导零,但您可能需要将ptr
转换为long
或更多可能uintptr_t
)
(AFAIK,C11标准不保证指针与%p
的任何特定文本表示 - 它们是特定于实现的;我正在考虑我的Linux / x86-64桌面)
如果你想要一些空终止字符串的长度(由指向其第一个字符的指针给出)使用strlen。
我不希望总内存占用我的指针(我可以通过sizeof得到)
这是非常错误的。所有指针都有相同的sizeof
(与指向内存的大小无关),在我的Linux / x86-64机器上是8个字节;所以例如
char buf[32];
int ptrtextlen = snprintf(buf, sizeof(buf), "%p", ptr);
printf("ptrtextlen=%d length(buf)=%zd\n", ptrtextlen, strlen(buf));
应该在我的Linux / x86-64桌面上输出ptrtextlen=6 length(buf)=5
int*heaptr = malloc(1024*sizeof(int));
printf("%zd", sizeof(heaptr));
将输出8(不是4096,这是成功调用malloc
时给出的内存区域的字节大小,因为sizeof(int)
在我的机器上为4)
PS。花几天时间阅读有关C11及其n1570规范的更多内容;看起来你很困惑。阅读C dynamic memory allocation。
答案 2 :(得分:-2)
指针的大小取决于机器的体系结构,使得32位系统的指针在内存中为4个字节,而64位系统将其作为内存中的8个字节。这些尺寸在特定系统上不会改变。了解这一点将有助于您设计所需的算法。您的函数或方法应首先检查特定计算机的指针大小。一旦知道了指针的大小,下一步就是检查它是否是小端或大端。一旦您能够确定正在使用哪个字节序,那么您就可以开始设计算法了。在您知道这两个是什么之后,您应该能够将实际的物理地址存储到字符数组中。然后,您可以从中删除所有非重要的前导零,为您留下任何非零的字符,并将它们保存到新的动态字符数组中。我建议使用unsigned char。然后,计算您从原始地址推断出的无符号字符数组中有多少字节。请注意,如果地址是十六进制值,则每2个字符为1个字节。因此,如果结果字符数组有8个值,则有4个字节;但是你想要在长度中返回8而不是以字节为单位返回4。
编辑 - 伪代码
unsigned getAddressLength( unsigned char& address ) {
// First Check to See if System is 16bit, 32bit, 64bit etc.
unsigned sizeInBytes = sizeof( address );
bool isBigEndian;
// test if Big or Little Endian;
if ( address is Big ) {
isBigEndian = true;
} else {
isBigEndian = false;
}
unsigned char[] addressBytes; // Evert 2 Characters In The Address String is 1 byte of memory.
if ( isBigEndian ) {
// Perform Algorithm This Way To Strip Out Non Significant 0s
} else {
// Same Thing But For Little Endian
}
// After Striping out All Non Significant leading 0s get the size in bytes of this new array
return (new length of character array);
}