C语言指针转换为intptr_t类型

2023-11-06

C语言指针转换为intptr_t类型

1、前言

  今天在看代码时,发现将之一个指针赋值给一个intptr_t类型的变量。由于之前没有见过intptr_t这样数据类型,凭感觉认为intptr_t是int类型的指针。感觉很奇怪,为何要将一个指针这样做呢?如是果断上网查查,发现我的感觉是错误的,所以,任何事情不能凭感觉,要弄清楚来龙去脉。先总结一下intptr_t类型,然后介绍指针与intptr_t类型的转换,最后给出测试程序。

2、intptr_t类型

  我接触最早的处理器是32位,目前64位处理器发展迅速。数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小。

位数 char short int long 指针
16  1个字节8位   2个字节16位  2个字节16位  4个字节32位 2个字节16位
32  1个字节8位   2个字节16位 4个字节32位  4个字节32位 4个字节32位
64  1个字节8位   2个字节16位  4个字节32位  8个字节64位 8个字节64位

为了保证平台的通用性,程序中尽量不要使用long类型。可以使用固定大小的数据类型宏定义,这些宏定义需要引用stdint.h头文件。

 1 /* There is some amount of overlap with <sys/types.h> as known by inet code */
 2 #ifndef __int8_t_defined
 3 # define __int8_t_defined
 4 typedef signed char         int8_t;
 5 typedef short int          int16_t;
 6 typedef int               int32_t;
 7 # if __WORDSIZE == 64
 8 typedef long int          int64_t;
 9 # else
10 __extension__
11 typedef long long int        int64_t;
12 # endif
13 #endif
14 
15 /* Unsigned.  */
16 typedef unsigned char         uint8_t;
17 typedef unsigned short int    uint16_t;
18 #ifndef __uint32_t_defined
19 typedef unsigned int          uint32_t;
20 # define __uint32_t_defined
21 #endif
22 #if __WORDSIZE == 64
23 typedef unsigned long int       uint64_t;
24 #else
25 __extension__
26 typedef unsigned long long int    uint64_t;
27 #endif

关于intptr_t的类型定义如下:

//intptr_t类型是为指针准备的
 1 /* Types for `void *' pointers.  */
 2 #if __WORDSIZE == 64
 3 # ifndef __intptr_t_defined
 4 typedef long int               intptr_t;
 5 #  define __intptr_t_defined
 6 # endif
 7 typedef unsigned long int    uintptr_t;
 8 #else
 9 # ifndef __intptr_t_defined
10 typedef int                    intptr_t;
11 #  define __intptr_t_defined
12 # endif
13 typedef unsigned int        uintptr_t;
14 #endif

从定义可以看出,intptr_t在不同的平台是不一样的,始终与地址位数相同,因此用来存放地址,即地址。

3、指针与intptr_t

  C语言指针用来保存变量或常量的地址,地址由处理器的位数决定。在windows程序中,经常用到句柄,其实就是一个地址,具备通用性,对底层进行了封装。先对这个理解不深刻,什么时候需要将指针转换为intptr_t类型。

4、测试程序

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <stdint.h>
 5 #include <string.h>
 6 #include <assert.h>
 7 
 8 #define ID_STR_LEN   12
 9 #define NAME_STR_LEN 10
10 
11 typedef struct student
12 {
13     char id[ID_STR_LEN];
14     char name[NAME_STR_LEN];
15     uint8_t age;
16 }student;
17 
18 student * create_student()
19 {
20     student *stu = (student *)malloc(sizeof(student));
21     if (stu == NULL)
22     return NULL;
23     memset(stu, 0, sizeof(student));
24     return stu;
25 }
26 
27 void *free_student(student *stu)
28 {
29     if (stu)
30     free(stu);
31 }
32 
33 static void init_student(student * stu)
34 {
35     assert(stu);
36     const char *id = "2013112210";
37     const char *name = "Anker";
38     uint8_t age = 21;
39     memcpy(stu->id, id, strlen(id));
40     memcpy(stu->name, name, strlen(name));
41     stu->age = age;
42 }
43 
44 static int handle_student(intptr_t handle)
45 {
46     if (handle == 0)
47     {
48     return -1;
49     }
50     student *stu = (student*)handle;
51     printf("id: %s\n", stu->id);
52     printf("name: %s\n", stu->name);
53     printf("age: %u\n", stu->age);
54     return 0;
55 }
56 
57 int main()
58 {
59     student *stu;
60     stu = create_student();
61     init_student(stu);
62     //将指针转换为intptr_t类型
63     intptr_t handle = (intptr_t)stu;
64     handle_student(handle);
65     free_student(stu);
66     return 0;
67 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言指针转换为intptr_t类型 的相关文章

  • LD_PRELOAD可以用来加载不同版本的glibc吗?

    角色阵容 big old app链接到旧版本glibc say glibc 2 12 我无法做任何事情来改变这一点 cute new addon o链接到较新的版本 glibc 2 23 This glibc 2 23位于非标准路径中 因为
  • GCC 如何自动知道包含 glib 库?

    我用 C 语言编写了一个简单的程序 它使用glib h 但是当我编译它时 我收到如下错误 gcc test c o test test c 3 18 fatal error glib h No such file or directory
  • 如何使用__malloc_hook?

    In GNU C 库参考手册 有一个示例程序 p 65 但我不知道这三句话是什么 malloc hook old malloc hook old malloc hook malloc hook malloc hook my malloc h
  • 如何将 C/C++ 应用程序移植到旧版 Linux 内核版本

    好吧 这只是一个有趣的练习 但是为一些较旧的 Linux 系统编译程序不会太难 不是吗 我可以访问几个运行 Linux 的古老系统 也许看看它们在负载下的表现会很有趣 举个例子 我们想要使用一些线性代数Eigen http eigen tu
  • Binutils LD 创建巨大文件

    我正在尝试创建尽可能小的 ELF 我创建了一个像这样的测试文件 NASM 语法 SECTION text dd 0xdeadbeef 使用此链接描述文件 SECTIONS text text 然后我检查了平面二进制文件的大小 并通过两种方式
  • 如何包装 glibc 库函数以自动使用“unsigned char”和“wchar_t”?

    我总是用char as unsigned char and wchar t as wint t 鉴于此 是否存在一种解决方案来更改函数接口以使用这些类型 无论是否重新编译 glibc 另请参阅这个问题 如何更改 wchar h 以使 wch
  • POSIX 取消点应该如何表现?

    我一直在研究 glibc nptl 取消点的实现 并将其与 POSIX 进行比较 除非我弄错了 否则它是完全错误的 使用的基本模型是 int oldtype LIBC ASYNC CANCEL switch to asynchronous
  • 在同一个进程中加载​​ musl libc.so 和 gcc libc.so ?

    我有一个用 musl libc 编译的共享库 readelf d libinterop d so Dynamic section at offset 0x8ecb0 contains 22 entries Tag Type Name Val
  • Fedora 28 / GLIBC 2.27 libm.so.6 logf() 和 powf() c++

    我确信其他 Fedora 28 用户会知道 该操作系统的 glibc 最近已更新为 glibc 2 27 除此之外 2 27 还添加了 logf 和 powf 的新实现 这导致我的应用程序无法在旧版 glibc 的发行版 例如 Debian
  • 单个主机上的多个 glibc 库

    我的 Linux SLES 8 服务器当前有 glibc 2 2 5 235 但我有一个程序无法在此版本上运行并且需要 glibc 2 3 3 是否可以在同一主机上安装多个 glibc 这是我在旧 glibc 上运行程序时遇到的错误 mya
  • getenv() 的全局变量?

    哪个全局变量保存了 getenv 的所有环境变量 在哪个 glibc 文件中 这个 var 填充了 env vars 我相信它是 environ 但是当我在 bash 中设置环境变量时 它只输出 SSH AGENT PID 环境变量 为什么
  • 可以自定义printf吗?

    我有一些需要经常打印的结构 现在 我在这个结构周围使用经典的打印包装器 void printf mystruct struct my struct if my struct NULL return printf value1 d value
  • Glibc - ucontext.h 中出现错误,但仅适用于 -std=c11

    我有这个最小的 helloworld 扩展包括ucontext h include
  • 隐藏链接到 .so 文件的第 3 方 .a 文件中的符号

    我正在构建一个共享 so 库 该库由多个 a 文件和调用它们的瘦 API 层组成 我只希望我的 API 和外部依赖项可见 因此我使用 GCC 提供的 隐藏 可见性构建代码 fvisibility hidden 然而 其中一个库是专有的第三方
  • 为什么标准输出不能被替换?

    出于教育目的 我尝试替换标准流 stdout stdin 和 stderr 我首先查找流的数据类型 我追溯到具有以下成员的 struct IO FILE gdb ptype IO FILE type struct IO FILE int f
  • 系统调用位于 glibc 源代码中的哪里

    所以我正在查看 linux glibc 源代码 但我没有看到它实际上在哪里做了任何事情 以下内容来自io chdir c但它表明了许多源文件 这里发生了什么 显然我错过了一些东西 秘密是什么 它在哪里进行系统调用或实际执行某些操作 stub
  • 在非标准位置无需 root 即可使用 glibc 构建 GCC

    我有一个没有 root 访问权限的系统 但我需要安装当前版本的 GCC 4 7 2 该系统正在运行 Linux 2 6 18 的 x86 64 版本 并且已经有 GCC 4 1 没有 C 支持 尽管 version 说它是用它构建的 编辑5
  • Yocto Bitbake Glibc 构建失败

    我正在尝试构建 Yocto 映像 但编译 glibc 时构建失败 如果我只跑 bitbake glibc c compile 我收到编译错误如下 usr src debug glibc 2 27 r0 git nptl pthread at
  • 使用 glibc 而不是默认库编译的 C 程序:执行时权限被拒绝

    这是我在 stackoverflow 上的第一个问题 所以我会尽力做好 Context 我想提供一个可以在每个 Linux 发行版上运行的程序 例如 一个将使用 C 11 的程序 在没有 C 11 库的系统上运行 为此 我想复制我的程序使用
  • getaddrinfo在程序中调用assert

    我正在使用 libcurl 开发一个程序 该程序创建一个线程 该线程又使用 libcurl 发出 HTTP 请求 但有时程序会因错误而崩溃 netlink 描述符上出现意外错误 9 在curl中关闭AsynchDNS之后 但问题依然存在 据

随机推荐