使用指针算法引用结构成员
Referencing a struct member with pointer arithmetic
我有一个结构定义,
struct liste{
unsigned int size;
unsigned int capacity;
char* data;
};
还有一个实例,
struct liste lst = {3, 4, "hi"};
我想做的是在不直接调用 lst.data
的情况下获取 data
成员。到目前为止,我已经能够得到一个指针,dataC
;
char* dataC = (char *) ((char *)&lst + 2 * sizeof(unsigned int));
从而打印 dataC
和 &lst.data
作为指针给出相同的输出。我认为取消引用 dataC
并将结果转换为 char *
会产生一个相同的指针 lst.data
但我得到了一个段错误。
我是不是遗漏了什么??
根据你的代码,dataC存储的不是数据“hi”的地址,而是lst.data的指针地址。你可以看到下面的代码。 dataC是lst.data的地址。 *dataC是字符串"hi"的地址,同lst.data.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<stdint.h>
struct liste{
unsigned int size;
unsigned int capacity;
char *data;
};
int main()
{
struct liste lst = {3, 4,"hi"};
char **dataC = (char **) ((char *)&lst + 2 * sizeof(unsigned int));
printf("datac = %s\n",(*dataC));
}
您的代码既不可移植也不坚固,因为结构内部可能有结构填充。如果你需要做一些像你在这里尝试的事情,你应该使用 offsetof
宏,它用于获取结构内成员的字节偏移量。示例:
#include <stdio.h>
#include <stddef.h> // offsetof
struct liste{
unsigned int size;
unsigned int capacity;
char* data;
};
int main (void)
{
struct liste lst = {3, 4, "hi"};
char** ptrptr = (char**) ((char*)&lst + offsetof(struct liste, data)) ;
puts(*ptrptr);
}
值得注意的是,(char*)&list
部分与我们正在寻找的 char 类型的数据无关。这只是一种逐字节迭代较大数据类型的方法,如果我们使用字符指针,C 允许这样做。我们最终得到一个指向结构内部(指针)data
位置的字符指针。通过将结果转换为 char**
,我们清楚地表明我们指向的是 char*
.
类似地,我们可以这样获取 capacity
成员:
unsigned int** pp_cap = (unsigned int**) ((char*)&lst + offsetof(struct liste, capacity)) ;
printf("%d\n", *pp_cap);
我有一个结构定义,
struct liste{
unsigned int size;
unsigned int capacity;
char* data;
};
还有一个实例,
struct liste lst = {3, 4, "hi"};
我想做的是在不直接调用 lst.data
的情况下获取 data
成员。到目前为止,我已经能够得到一个指针,dataC
;
char* dataC = (char *) ((char *)&lst + 2 * sizeof(unsigned int));
从而打印 dataC
和 &lst.data
作为指针给出相同的输出。我认为取消引用 dataC
并将结果转换为 char *
会产生一个相同的指针 lst.data
但我得到了一个段错误。
我是不是遗漏了什么??
根据你的代码,dataC存储的不是数据“hi”的地址,而是lst.data的指针地址。你可以看到下面的代码。 dataC是lst.data的地址。 *dataC是字符串"hi"的地址,同lst.data.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<stdint.h>
struct liste{
unsigned int size;
unsigned int capacity;
char *data;
};
int main()
{
struct liste lst = {3, 4,"hi"};
char **dataC = (char **) ((char *)&lst + 2 * sizeof(unsigned int));
printf("datac = %s\n",(*dataC));
}
您的代码既不可移植也不坚固,因为结构内部可能有结构填充。如果你需要做一些像你在这里尝试的事情,你应该使用 offsetof
宏,它用于获取结构内成员的字节偏移量。示例:
#include <stdio.h>
#include <stddef.h> // offsetof
struct liste{
unsigned int size;
unsigned int capacity;
char* data;
};
int main (void)
{
struct liste lst = {3, 4, "hi"};
char** ptrptr = (char**) ((char*)&lst + offsetof(struct liste, data)) ;
puts(*ptrptr);
}
值得注意的是,(char*)&list
部分与我们正在寻找的 char 类型的数据无关。这只是一种逐字节迭代较大数据类型的方法,如果我们使用字符指针,C 允许这样做。我们最终得到一个指向结构内部(指针)data
位置的字符指针。通过将结果转换为 char**
,我们清楚地表明我们指向的是 char*
.
类似地,我们可以这样获取 capacity
成员:
unsigned int** pp_cap = (unsigned int**) ((char*)&lst + offsetof(struct liste, capacity)) ;
printf("%d\n", *pp_cap);