简体   繁体   English

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

[英]Referencing a struct member with pointer arithmetic

I've got a struct definition,我有一个结构定义,

struct liste{
    unsigned int size;
    unsigned int capacity;
    char* data;
};

and an instance,和一个实例,

struct liste lst = {3, 4, "hi"};

and what I'm trying to do is get the data member without directly calling lst.data .我想要做的是在不直接调用lst.data情况下获取data成员。 So far I've been able get a pointer, dataC ;到目前为止,我已经能够得到一个指针dataC

char* dataC = (char *) ((char *)&lst + 2 * sizeof(unsigned int));

whereby printing dataC and &lst.data as pointers gives the same output.从而打印dataC&lst.data作为指针给出相同的输出。 I thought dereferencing dataC and casting the result to a char * would yield a pointer identical lst.data but I get a segfault.我认为取消引用dataC并将结果转换为char *会产生一个与lst.data相同的指针,但我得到了一个段错误。

Is there something I'm missing??有什么我想念的吗??

According to your code, dataC does not store the address of the data "hi", but the address of the pointer of lst.data.根据你的代码,dataC 并没有存储数据“hi”的地址,而是 lst.data 的指针地址。 You can see the code below.你可以看到下面的代码。 dataC is the address of lst.data. dataC 是 lst.data 的地址。 *dataC is the address of the string "hi", the same as 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));

}

Your code is neither portable nor rugged, because there might be struct padding inside the struct.您的代码既不便携也不坚固,因为结构内部可能有结构填充。 If you need to do something like you attempt here, you should be using the offsetof macro, which is used to get the byte offset of a member inside a struct.如果你需要做一些你在这里尝试的事情,你应该使用offsetof宏,它用于获取结构内成员的字节偏移量。 Example:例子:

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

Notably the (char*)&list part has nothing to do with the data we are looking for being of char type.值得注意的是(char*)&list部分与我们正在寻找的 char 类型数据无关。 This is simply a way of iterating through a larger data type byte by byte, which C allows if we use character pointers.这只是一种逐字节迭代更大数据类型的方法,如果我们使用字符指针,C 允许这样做。 We end up with a character pointer pointing at the location of (the pointer) data inside the struct.我们最终得到一个字符指针,指向结构内(指针) data的位置。 By casting the result to char** , we make it clear that whatever we are pointing at is a char* .通过将结果转换为char** ,我们清楚地表明我们指向的是char*

Similarly, we could get the capacity member like this:同样,我们可以像这样获得capacity成员:

unsigned int** pp_cap = (unsigned int**) ((char*)&lst + offsetof(struct liste, capacity)) ;
printf("%d\n", *pp_cap);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM