如果我有一个代码:
typedef struct s_ {
int a;
char* b;
} s;
int main()
{
s* st = malloc(sizeof(s));
st->b = malloc(20*sizeof(char));
st->a = 1;
st->b = "foo";
}
这里是否可以使用偏移量访问char数组中的数据?例如,这里的偏移量是4个字节,我知道,可以使用offsetof((宏进行计算,但我不能使用指针算法访问数据,如:
printf("%s", (char*)(st+4));
如果有人能在这里帮忙,我会非常高兴:(
答案可能令人惊讶:st+4
实际上将指针增加了32个字节!
这是因为st
的类型是struct s_ *
,当您在其中添加4时,它会增加结构大小的4倍。
为了移动4个字节,您需要先将指针投射到char*
,然后递增
试试这个:printf("%s", *(char**)((char*)st + 4));
编辑:添加*(char**)
。
之所以需要它,是因为通过增加指针,我们不会得到字符串的开头,而是得到指向字符串开头的指针的地址。所以我们需要将它强制转换为正确的类型并取消引用它
您可以使用(char *)st + offsetof(s, b)
计算char *
元素b
的字节地址(这是一个char **
值(;因此,您可以使用以下代码访问字符串:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct s_
{
int a;
char *b;
} s;
int main(void)
{
s *st = malloc(sizeof(s));
st->b = malloc(20 * sizeof(char));
st->a = 1;
strcpy(st->b, "foo");
char *str = *(char **)((char *)st + offsetof(s, b));
printf("[%s]n", str);
return 0;
}
输出是包含[foo]
的一行。
现在你知道为什么你不想这样做了——让编译器为你解决它:
printf("[%s]n", st->b);
这个问题越来越接近于在C中动态定义struct
可能吗?
如果使用printf("%s", (char*)(st+4));
,结果已偏移4*结构的
你想打印第四个字符,可以这样写
char *ptr = null;
ptr = st;
printf("[%s]",ptr);