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)
vs
sizeof(int*)
@Kevin只是快速查看了一下,我找不到任何证据表明
sizeof(size\u t)
保证等同于
sizeof(int*)
,所以我更新了答案。干杯:)是的,我问过OP地址的长度。为了知道长度,您需要首先知道大小,因为不同的体系结构,并且知道endian也很重要,因为字节顺序。然后,将不重要的前导0剥离出来,并将结果存储到新的字符数组中。此字符数组的大小或长度将是OP正在查找的指针地址的长度,因为每两个非0字符代表一个字节的内存寻址。我确实犯了一个错误;如果地址是十六进制的;每2个字符为1字节