宏CONTAINING_RECORD,可以直接根据结构体成员指针找到结构体指针。
我们看一下它的定义:
#define CONTAINING_RECORD(addr,type,field) ((type*)((unsigned char*)addr - (unsigned long)&((type*)0)->field))
// addr: 结构体中某个成员变量的地址
// type: 结构体的原型
// field: 结构体的某个成员(与前面相同)
为什么这样就能得到结构体指针?
这个得益于结构体在申请内存空间是一段连续的地址,我们可以通过其中某个成员变量的地址,减去该成员的偏移来得到该成员所在结构体的指针。
那么为何(unsigned long)&((type*)0)->field))能得到某结构体成员的偏移?
这里可以假设某结构体指针地址是0000000,那么该成员的地址就是该成员对于其结构体的偏移
为了论证我们的猜想是对的,你可以无限次数运行以下代码
#include <windows.h>
#include <stdio.h>
struct T{
int a;
int b;
int c;
};
int main()
{
T t = {1,2,3};
printf("结构体指针地址:\t%p\n", &t );
printf("结构体成员a指针地址:\t%p\n", &t.a );
printf("结构体成员b指针地址:\t%p\n", &t.b );
printf("结构体成员c指针地址:\t%p\n", &t.c );
printf("...\n");
printf("下面利用结构体成员c来推算结构体的指针\n");
int *cc = &t.c;
T *tt = CONTAINING_RECORD(cc, T, c);
printf("结构体(T*)0指针地址:\t%p\n", ((T*)0) );
printf("结构体成员c的偏移值:\t%d\n", &((T*)0)->c );
printf("结构体指针地址:\t%p\n", tt );
system("pause");
return 0;
}
运行结果:
分享到:
相关推荐
下面小编就为大家分享一篇基于C#调用c++Dll结构体数组指针的问题详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
C#调用C++ dll, 包括结构体, 数组, 函数指针, 字符串等等
主要介绍了Go语言指针访问结构体的方法,涉及Go语言指针及结构体的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
可以设一个指针变量,来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。 设p是指向结构体变量的数组,则可以通过以下的方式,调用指向的那个结构体中的成员: (1)结构体变量.成员名。如,stu.num...
在结构体或类中, 指针访问其成员函数或变量通过 “->” 运算符或者看代码注释部分, 注释部分的操作不推荐: #include #include using namespace std; struct STRUCT { string hello; }; int main() { STRUCT *...
C++结构体数组 一个结构体变量中可以存放一组数据(如一个学生的学号、姓名、成绩等数据)。如果有10个学生的数据需要参加运算,显然应该用数组,这就是结构体数组。结构体数组与以前介绍过的数值型数组的不同之处...
C++结构体类型的定义和初始化 有时需要将不同类型的数据组合成一个有机的整体,以供用户方便地使用。这些组合在一个整体中的数据是互相联系的。例如,一个学生的学号、姓名、性别、年龄、成绩、家庭地址等项,都是这...
1、结构体指针变量的定义以及通过结构体指针变量调用成员变量的方法; 2、讲解和演示结构体对象做形式参数与结构体指针变量做参数的作用与区别;
(2)定义一个结构体类型student,写一个函数,根据学号或者成绩,对包含有n个学生的结构体数组进行排序,学生的结构体至少包括3个成员(学号,姓名,入学分数等),比较结构体变量的大小时,可以根据其学号或者分数...
operator->() 重载 -> 号,当智能指针指向的数据类型为⾃定义的结构体时,通过 -> 运算符可以获取其内部的指定成员。 operator =() 重载了 = 赋值号,从⽽可以将 nullptr 或者⼀个右值 unique_ptr 指针直接赋值给...
C++智能指针详解 1、概述 我们知道除了静态内存和栈内存外,每个程序还有⼀个内存池,这部分内存被称为⾃由空间或者堆。程序⽤堆来存储动态分配的对象即那些 在程序运⾏时分配的对象,当动态对象不再使⽤时,我们的...
operator->() 重载 -> 号,当智能指针指向的数据类型为⾃定义的结构体时,通过 -> 运算符可以获取其内部的指定成员。 operator =() 重载了 = 赋值号,从⽽可以将 nullptr 或者⼀个右值 unique_ptr 指针直接赋值给...
memset初始化std::string对象时,按字节顺序将std::string对象所在空间清零,破坏了std::string对象的成员结构,使Myroxy指针资源变为野指针,操作其迭代器会出现不可预知的异常,在存储字符串时可能分配了不必要的...
C C++结构体的一个高级特性――指定成员的位数 78 C C++中的近指令 远指针和巨指针 80 从两道经典试题谈 C C++中联合体(union)的使用 81 基于 ARM 的嵌入式 Linux 移植真实体验 83 基于 ARM 的嵌入式 Linux 移植...
本书共分16章。介绍了C++的历史沿革、C++的开发环境VisualStudio2010,讲解了...预处理命令的功能、文件包含的使用,指针的概念和作用,C++中的结构体、共用体、枚举和用户自定义,类的定义、类与对象、类成员函数等。
operator->() 重载 -> 号,当智能指针指向的数据类型为⾃定义的结构体时,通过 -> 运算符可以获取其内部的指定成员。 operator =() 重载了 = 赋值号,从⽽可以将 nullptr 或者⼀个右值 unique_ptr 指针直接赋值给...
要想理解 C++ 的 this 指针,我们先把下面的 C++ 代码转换成 C 的代码 class Car { public: int m_price; // 成员变量 void SetPrice(int p) // 成员函数 { m_price = p; } }; int main() { Car car; car....
所以,标准C中的结构体是不允许包含成员函数的,当然C++中的结构体对此进行了扩展。那么,我们在C语言的结构体中,只能通过定义函数指针的方式,用函数指针指向相应函数,以此达到调用函数的目的。 函数指针 函数...
1.数据类型转换:(double)2.结构体:struct,memcpy,memset3.格式化输出:\,snprintf4...结构体成员变量的使用与其它变量的使用相同 结构体数组:结构体可以被定义为数组变量,本质上与其他类型的数组变量没有区