运行结构并打印所有值?

时间:2011-05-20 15:38:59

标签: c struct structure

我有一个指向结构的指针,我想通过反复试验获取所有成员。我试图通过将指针递增1并对其进行解除来完成结构。它应该从结构中返回一个正确的值(每i*sizeof(int)次),但事实并非如此。

我做错了什么?

fn (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
{

    /*
     assume that all struct members are int types

     typedef    struct 
     {
     mach_msg_bits_t    msgh_bits;
     mach_msg_size_t    msgh_size;
     mach_port_t        msgh_remote_port;
     mach_port_t        msgh_local_port;
     mach_msg_size_t    msgh_reserved;
     mach_msg_id_t      msgh_id;
     } mach_msg_header_t;

     size of the struct is 24.
     */

    printf("ID: %d \n",InHeadP->msgh_id); //prints 'ID: 1337'
    printf("Ptr: %p\n",InHeadP);

    for (int i = 0; i <= 24; i++)
    {
        int deref = *((int*)(InHeadP+i));
        printf("InHeadP[%d]=%d\n",i,deref);
            //no sign of 1337 anywhere

    }
}

P.S。我知道我不应该这样做,但这仅用于测试目的。

5 个答案:

答案 0 :(得分:5)

因为InHeadPmach_msg_header_t*,所以向其添加一个整数实际上会将整数乘以sizeof(mach_msg_header_t),就好像你正在索引一个mach_msg_header_t的数组(和实际上是数组索引的工作方式)。您需要在对其执行算术之前将InHeadP投射到int* ,即便如此,因为结构有六个字段,i应该只到达6,而不是24。

答案 1 :(得分:3)

迭代结构的首选方法是创建一个函数,该函数返回给定索引的字段的值或地址。请注意,如果结构中成员的顺序发生变化,则此函数也必须更改:

int * Index_Of(unsigned int index, mach_msg_header_t * p_struct)
{
    switch (index)
    {
        case 0:  return (int *) &(p_struct->msgh_bits);
        case 1:  return (int *) &(p_struct->msgh_size);
        case 2:  return (int *) &(p_struct->msgh_remote_port);
        case 3:  return (int *) &(p_struct->msgh_local_port);
        case 4:  return (int *) &(p_struct->msgh_reserved);
        case 5:  return (int *) &(p_struct->msgh_id);
    }
    return 0;
}

请记住,将结构视为连续字段(成员)是不可取的,因为允许编译器在结构成员之间添加填充。因此,除了名称之外访问字段的任何方法都是危险的,并且将导致非常困难的错误。

BTW,将每个字段视为int也很危险。如果将任何类型更改为其他类型,例如double,则代码将中断。编译器不会捕获错误,因为转换告诉编译器你知道你在做什么。

您可以“转动图片”并实施访客模式:

struct Visitor_Void
{
    void (*fn_msgh_bits)(mach_msg_bits_t);
    void (*fn_msgh_size)(mach_msg_size_t);
    void (*fn_msgh_remote_port)(mach_port_t);
    void (*fn_msgh_local_port)(mach_port_t);
    void (*fn_msgh_reserved)(mach_msg_size_t);
    void (*fn_msgh_id)(mach_msg_id_t);
};


void Visit_Members(mach_msg_header_t * p_header,
                   struct Visitor_Void * p_visitor)
{
    (p_visitor->fn_msgh_bits)(p_header->msgh_bits);
    (p_visitor->fn_msgh_size)(p_header->msgh_size);
    (p_visitor->fn_msgh_remote_port)(p_header->msgh_remote_port);
    (p_visitor->fn_msgh_local_port)(p_header->msgh_local_port);
    (p_visitor->fn_msgh_reserved)(p_header->msgh_reserved);
    (p_visitor->fn_msgh_id)(p_header->msgh_id);
    return;
}

答案 2 :(得分:1)

不,你不应该这样做!

这里特别错误

for (int i = 0; i <= 24; i++)
{
    int deref = *((int*)(InHeadP+i));
    printf("InHeadP[%d]=%d\n",i,deref);
}

是你打印24个不同结构的第一个int。

答案 3 :(得分:0)

当你调用(int *)(InHeadP + i)时,你正在对mach_msg_header_t进行指针运算,大小为24.所以你的第一次迭代是在struct的开头,你的第二次迭代就在你的struct之后。您正在访问其他一些内存。

尝试(((int *)InHeadP)+ i)。

答案 4 :(得分:0)

等一下,这是错的:

 int deref = *((int*)(InHeadP+i));

你想要

int deref == *((int*)InHeadP+i)

每次通过循环跳过24个字节,而不是4个。