C 获取指针的长度(不是sizeoff)
由于某些特殊原因,我需要获取指针的长度(字符)。 如果指针为:C 获取指针的长度(不是sizeoff),c,pointers,C,Pointers,由于某些特殊原因,我需要获取指针的长度(字符)。 如果指针为: 0x2ADF4 它应该返回5, 因为指针中有5个字符。 事实上,我希望将指针的十六进制表示形式的长度转换为整数。 此数字应随指针的不同而不同。 请注意,我不希望我的指针(我可以通过sizeoff获得)占用总内存。指针的大小取决于机器的体系结构,32位系统的指针内存为4字节,64位系统的指针内存为8字节。这些大小在特定系统上不会更改。了解这一点将帮助您设计所需的算法。您的函数或方法应该首先检查特定机器的指针大小。一旦知道指针的大小,
0x2ADF4
它应该返回5
,
因为指针中有5个字符。
事实上,我希望将指针的十六进制表示形式的长度转换为整数。
此数字应随指针的不同而不同。
请注意,我不希望我的指针(我可以通过sizeoff获得)占用总内存。指针的大小取决于机器的体系结构,32位系统的指针内存为4字节,64位系统的指针内存为8字节。这些大小在特定系统上不会更改。了解这一点将帮助您设计所需的算法。您的函数或方法应该首先检查特定机器的指针大小。一旦知道指针的大小,下一步就是检查它是小端还是大端。一旦您能够确定正在使用哪个endian,那么您就可以开始设计您的算法了。在您知道这两个是什么之后,您应该能够将实际的物理地址存储到字符数组中。从那里,您可以去掉所有不重要的前导零,留下任何非零字符,并将它们保存到新的动态字符数组中。我建议对此使用未签名字符。然后计算从原始地址推断出的无符号字符数组中有多少字节。注意:如果地址为十六进制值,则每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);
}
您可以将ptr转换为type
intptr\u 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;
}
因此,您需要指针的一些文本表示的长度(注意术语,您不需要保存该指针的分配内存区域的大小),通常是指向某个内存位置的指针的长度(但可能不是) 您应该注意到,它们都返回写入某个缓冲区的字节数(包括终止的零字节),并且都接受
NULL
缓冲区,因此您可以编写:
int ptrtextlen = sprintf(NULL, "%p", ptr);
在您的情况下(对于ptr
为0x2ADF4),它将返回8(因为0x2ADF4
需要7个字节,从0
开始,到4
,再加上一个终止的零字节)。顺便说一句,阅读更多关于sprintf的信息(您可以使用它来获取一些前导零,但您可能需要将ptr
转换为long
或更可能的uintptpr\t
)
(顺便说一句,C11标准不保证使用%p
对指针进行任何特定的文本表示-它们是特定于实现的;我考虑的是我的Linux/x86-64桌面)
如果需要以null结尾的字符串(由指向其第一个字符的指针给出)的长度,请使用
我不希望指针占用总内存(我可以通过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长度(buf)=5
int*heaptr = malloc(1024*sizeof(int));
printf("%zd", sizeof(heaptr));
将输出8(不是4096,它是成功调用malloc
时给出的内存区域的字节大小,因为sizeof(int)
在我的机器上是4)
另外,花几天时间阅读更多关于产品及其规格的信息;看来你很困惑。阅读。另外,为什么指针0x0ADF4
而不是0x0000ADF4
或0xADF4
?这完全取决于(任意)选择的格式。为什么会有前导零?这个值的“长度”不应该是4吗?为什么指针之间“应该”不同?这不是“指针的长度”。这是“十六进制表示的整数指针的长度”,但您希望这样做的“特殊原因”是什么呢。在我看来像是一些。你应该编辑你的问题来激发它!可能您正在输出一些指针值表,但是有更好的方法来实现与数据的文本对齐。我已经用实际代码进行了尝试,我的ptr是“0028FF34”
输出为6
@Badda这就是数字的工作原理:p前导0纯粹是格式,并不代表实际值的任何差异(查看注释,op似乎希望删除前导0)。您可能应该将其转换为intptr\t
。我不确定标准中是否有关于sizeof(size\u t)
vssizeof(int*)
@Kevin只是快速查看了一下,我找不到任何证据表明sizeof(size\u t)
保证等同于sizeof(int*)
,所以我更新了答案。干杯:)是的,我问过OP地址的长度。为了知道长度,您需要首先知道大小,因为不同的体系结构,并且知道endian也很重要,因为字节顺序。然后,将不重要的前导0剥离出来,并将结果存储到新的字符数组中。此字符数组的大小或长度将是OP正在查找的指针地址的长度,因为每两个非0字符代表一个字节的内存寻址。我确实犯了一个错误;如果地址是十六进制的;每2个字符为1字节