使用指针算法引用结构成员

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);