`
cwqcwk1
  • 浏览: 86839 次
文章分类
社区版块
存档分类
最新评论

c++根据结构体成员指针找到结构体指针

 
阅读更多

宏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#中,使用MarshalAsAttribute特性来申明结构体成员的类型和长度,例如: [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] pData; 在C#中,使用StructLayoutAttribute特性来申明结构体的....

    C++结构体参数与结构体指针参数区别Demo

    当调用该函数时,所有结构体成员的值会被复制到函数内部的局部变量中。这种方式简单明了,但如果结构体较大,复制操作可能会消耗较多的时间和内存。 2. 结构体指针参数: 另一种方法是通过指针传递结构体。在这种...

    VC++结构体成员变量和方法

    本篇文章将深入探讨VC++中结构体的成员变量和方法,以及如何实现结构体成员的调用。 1. **结构体与类的区别** - 默认访问修饰符:在C++中,类的成员默认是私有的(private),而结构体的成员默认是公有的(public...

    结构体问题

    ### 结构体数组与结构体指针 结构体也可以被用来创建数组,或者通过指针处理数组中的元素: ```cpp Student students[3]; // 结构体数组 students[0] = {"赵六", 22, 86.0f}; // ... Student* pStu = students; // ...

    c++程序包(结构体 文件 指针)

    在压缩包中,可能会包含使用指针访问结构体成员,动态分配内存,以及通过指针传递参数的示例。 链表是一种动态数据结构,与数组不同,它不必预先分配固定大小的空间。链表由节点组成,每个节点包含数据和指向下一个...

    成员运算符与指向结构体成员运算符的区别

    成员运算符(`.`)与指向结构体成员运算符(`-&gt;`)是C/C++语言中处理结构体数据类型时非常关键的两个运算符。它们虽然功能相似,但使用场景和语法结构上有着显著的不同。 首先,成员运算符`.`用于访问结构体变量的...

    JNA 转java接口以及指针结构体解析

    在"JNA 转java接口以及指针结构体解析"这个主题中,我们将深入探讨如何使用JNA来处理C语言中的结构体和指针。 首先,理解JNA的基本工作原理至关重要。JNA通过定义一个`Interface`,该接口中的方法对应于要调用的...

    C#调用C++动态库,执行回调函数并传递结构体参数

    注意,由于跨语言调用,结构体成员的排列顺序、大小和对齐方式必须一致。 接下来,我们需要定义一个C++接口,这个接口包含了一个接受回调函数和结构体参数的函数。在C++中,这可能看起来像这样: ```cpp extern "C...

    结构体、指针的应用

    5. 可能涉及传递结构体指针给函数,展示如何在函数内部操作结构体。 了解了结构体和指针的基本概念后,我们可以利用它们实现各种高级编程技巧,如动态内存分配、数据结构的实现、回调函数等。在实际项目中,熟练...

    C++中指向结构体变量的指针

    在C++编程语言中,结构体(struct)是一种自定义数据类型,它允许我们将多个不同类型的变量组合成一个单一的实体。结构体变量的指针是一个非常重要...理解和熟练掌握结构体指针的使用,是提升 C++ 编程技能的关键一步。

    调用示例.rar_C#调用c++ dll_C#调用函数指针_C#调用结构体_结构体_调用C dll

    C#调用C++ dll, 包括结构体, 数组, 函数指针, 字符串等等

    408结构体对齐-typedef-结构体指针-c++引用

    ### 结构体对齐、typedef、结构体指针与C++引用详解 #### 一、结构体对齐 **结构体对齐**是指在结构体中的成员变量在内存中的排列方式,这种排列是为了提高CPU访问内存的速度。由于现代处理器的设计倾向于以一定的...

    C/C++结构体序列化配置模板化

    本主题探讨的是如何利用C++的模板机制来实现结构体的序列化配置,以提高代码的可复用性和灵活性。 首先,我们需要理解C++的模板。模板是C++中的一个强大特性,允许我们编写通用的代码,可以应用于多种数据类型。这...

    c++结构体在ios端解析

    在iOS开发中,C++结构体的使用是一个重要的知识点,特别是在需要跨语言交互或利用C++的高效性能时。本文将深入探讨C++结构体在iOS应用中的解析过程,以及如何在Objective-C或Swift中有效地利用它们。 首先,C++...

    详解C++中的指针结构体数组以及指向结构体变量的指针

    通过这个例子,我们可以看到,指针结构体数组和指向结构体变量的指针是C++中处理复杂数据结构的有效工具。它们允许我们高效地操作和管理大量数据,尤其是在需要动态修改和查询数据时。理解这些概念对于深入学习C++...

    C++结构体与类指针知识点总结

    结构体指针是指向结构体变量的指针,可以通过指针访问结构体成员。 例如: ```cpp struct STRUCT { string hello; }; int main() { STRUCT *str = new STRUCT; str-&gt;hello = "Hello"; cout &lt;&lt; str-&gt;hello ; ...

    C#调用C++ Dll关于结构体数组引用的传递及解析使用的展示代码

    此外,还定义了一个名为`GetDeviceIdList`的函数,它接收一个`DEVICE_INFO`结构体数组的指针以及一个整型引用`count`作为参数。 #### C#中的结构体定义 接下来,在C#中定义相应的结构体以匹配C++中的定义: ```...

    C++结构体/函数定义转换C#函数定义/结构体

    - C++的结构体成员排列可能与C#不同,需要考虑内存对齐问题。 - 在C#中,可能需要使用`[StructLayout(LayoutKind.Sequential)]`来指定布局,以匹配C++的结构体。 3. **函数定义转换**: - C++的函数指针在C#中...

    C++结构体作为参数Demo

    在本示例"C++结构体作为参数Demo"中,我们将探讨如何将结构体作为函数参数来传递,以及这背后的内存管理和性能考虑。 首先,让我们了解结构体的基本概念。结构体允许我们将相关的数据项组合在一起,形成一个复合...

    C/C++结构体详解

    C/C++结构体详解 结构体(struct)是一种自定义的数据类型,它可以包含不同数据类型的成员,具有数组所不具备的一些功能特性。结构体的定义使用 struct 修饰符,例如:struct test { float a; int b; }; 定义了一个...

Global site tag (gtag.js) - Google Analytics