免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: lxyscls
打印 上一主题 下一主题

[C] 请问如何通过结构体的基地址和偏移来操作其成员变量? [复制链接]

论坛徽章:
0
1 [报告]
发表于 2011-11-18 10:28 |显示全部楼层
本帖最后由 keytounix 于 2011-11-18 13:31 编辑

1.
你这个需要考虑编译器优化时候数据的对齐问题不?
如果到这样的结构体
struct M_t
{
char a;
int b;
char *c;
}
会不会出问题?
struct M_t
{
char a;
int b;
char *c;
}__attribute__(aligned(2))
这样 属性弄一下 ,
是否会好一点呢?

2.
个人有点疑惑
既然有指针pst,还有元素m了
pst->m
不就可以弄好了吗?
如果要操作addr开始的size个单 元,
memset(addr,size,0)
不就可以了吗?

论坛徽章:
0
2 [报告]
发表于 2011-11-18 13:40 |显示全部楼层
本帖最后由 keytounix 于 2011-11-18 13:45 编辑

回复 12# yulihua49

惭愧

JSON是啥
我刚百度了,
看了很久
没看明白
隔行如隔山啊

论坛徽章:
0
3 [报告]
发表于 2011-11-18 17:40 |显示全部楼层
回复 14# yulihua49


    用C语言
除了宏

你能实现这个?

论坛徽章:
0
4 [报告]
发表于 2011-11-19 16:43 |显示全部楼层
本帖最后由 keytounix 于 2011-11-19 16:51 编辑

回复 16# yulihua49


   我的难点在于
用C怎么得到一个结构的名称

比如
struct test
{
int a;
char b;
long c;


}

test t;
t.a=1
t.b=2;
t.c =3;

这个是事实存在的

现在我们并不知道这个test结构体

拥有哪些成员

你是怎么用C得到这个结构体的成员名呢?

还有

我是看谭好强 的C启蒙的

貌似并没看到哪里有说C的什么模版的

倒是C++里面有这个东西

如果你扯上模板了,

我是不是可以说 超出C的范围了?


你怎么知道他的成员名称?

论坛徽章:
0
5 [报告]
发表于 2011-11-20 00:12 |显示全部楼层
本帖最后由 keytounix 于 2011-11-20 00:31 编辑

回复 19# yulihua49

佩服!

你这个方法确实很巧!

也很好!

看完后我 有点启发

你是通过构造一个模版

但是还是需要通过一个"模版"

既然这样,

为什么不在结构体本身下功夫?

LZ的结构体信息
typedef struct {

        short a;

        char *b;

        char *c;

} xx_stu_t;

#define short_t 1
#define char_p_t 2
.....
现在我们构建一个新的结构体
#define JSON_STRUCT_FLAG "json"
typedef JSON_STRUCT
{
char * json_struct_FLAG;
char * seg_size;//用动态内存依次存放xx_stu_t中的数据类型;
char * seg_name;用动态内存molloc依次存放xxx_stu中的段名称
xx_stu_t stu;
} J_xx_stu_t;

比如LZ的结构体信息
可以打包成JSONstruct他、如下

J_xx_stu_t j_stu;


j_stu.json_struct_FLAG<-  JSON_STRUCT_FLAG



j_stu.seg_size=malloc(10);

j_stu.seg_size[0]=short_t;
j_stu.seg_size[1]=char_p_t;
j_stu.seg_size[2]=char_p_t;

j_stu.seg_name<- "a,b,c"


struct_to_json(JSON * json,void * json_struct);

这个相比你那个来说有一个优点就是
模版都不要了
也就是说适合所有的按照JSON_STRUCT 结构这种格式封装的结构体
你那个只适合按照你那个模版构造的结构体
但是缺点也是很明显的
就是
1.
json_struct这个东西封装了 数据类型和 结构体成员名称,
这个增加了额外的额外的空间,
如果处理大批量数据,
这个就有点悬了

2.
存在偏移量计算的问题,
因为编译器优化的时候,
可能会把结构体打乱,
__attribute__(pakged)能处理这个问题?

你的那个是否也会存在这个问题?

论坛徽章:
0
6 [报告]
发表于 2011-11-20 00:40 |显示全部楼层
本帖最后由 keytounix 于 2011-11-20 09:11 编辑

回复 21# yulihua49


    写了上面这个,我又想起另外一种方式,这个是我觉得最安全最可靠的
想的有点仓促,写出来可能会有很多错误,欢迎指正


typedef struct {

        short no;

        char *name;

        char * class;

} xx_stu_t;

xx_stu_t stu_t{100,"li4","class 4"}
这个结构体改造

typedef struct {

int32 num_of_seg;//存放字段的总数      
char * *seg_1;//不管他叫什么名称,反正我们在调用他时不需要,只需要偏移量

............

} J_stu_t __attribute__(pakged);


在a.c中
初始化LZ这个结构体如下


J_stu_t j_stu;
j_stu.num=3;

*j_stu.name<---"name:li4"
*j_stu.class<---"class:class 4"
......

注意这个
因为都是char **类型和
int32型
那么数据将是很对齐的东西

这意味着在这个结构体 存储的东西将是如下结构
&jst地址开始信息如下
&jst:        3
&jst+4:   addr1
&jst+8:   addr2
&jst+12:  addr3


---------------
addr1:  "no,100"
addr2:  "name,li4"
addr3:  "class,class 4"

这样岂不是很好?

在b.c中,我们不需要知道J_STU_t的具体内容
只需要知道一个事实就是


J_STU_t第一个4字节单元存放的是元素的个数
以后的都是指针


在struct_to_json()函数中

int struct_to_json(JSON * json,J_STU_t * jst)
{
int num;
memcpy(&num,jst,4)
//这个就获得了元素的数目
#define N 100
char buf[N]


#define  get_seg(seg_index,buf) \
do{                                              \
      memset(buf,0x00,N);            \
      memcpy(buf,*(jst + seg_index* 4),strlen(*(jst + seg_index* 4));\
}while(0);

}

for i<-  [1,num]
get_seg(i,buf);
func(json,buf);
end for

}

如此不是很好吗?



这个 方法的优点很明显

就是不会出现因为编译器优化造成的偏移量 计算错误的问题

为什么?
因为都是以4字节递增的
int  char ** 都是4字节
这个是非常安全的,
编译器优化或者不优化,都不会出现问题

另外缺点
可能体现在内存上

首先,结构体的开销可能不变
为什么?
虽然结构体中增加了一个int变量,
但是考虑到对齐问题,这个可能是一样的

当然上面给出的结构体 是不能体现这个结论的

其次,存储字段存放的额外开销
也就是每个字段 增加了  strlen(seg_name)+ 1个冒号这个开销
粗略估算 大概每一个字段增加9+1=10个字节左右


这些是需要考虑的

论坛徽章:
0
7 [报告]
发表于 2011-12-06 16:42 |显示全部楼层
回复 26# yulihua49


    一旦扯上数据库就有点晕乎
  我打过交道的只有sqlite

论坛徽章:
0
8 [报告]
发表于 2011-12-07 16:31 |显示全部楼层
本帖最后由 keytounix 于 2011-12-07 16:33 编辑

回复 28# yulihua49


    我认真看了你给的那个连接

   数据库里面大批量的数据操作

  采用你的这个 模版方法 大概是最好的了, 最利于维护的了

  我那个方法还是没有跳出C的局限

  也许认真学习一下数据库和java对开拓视野有很大的好处

论坛徽章:
0
9 [报告]
发表于 2011-12-07 16:47 |显示全部楼层
回复 30# yulihua49


    没走题
  还是结构体的问题
呵呵
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP