如何在C中表示其内容的位中打印结构对象?

时间:2013-09-23 06:33:06

标签: c struct

我有以下c程序

     struct in_addr {
            unsigned long s_addr;  // load with inet_aton()
        };

        struct sockaddr_in {
            short            a;  
            unsigned short   b;    
            struct in_addr   c;     
            char             d[8];  
        };

        int main(int argc, char** argv) {

            struct sockaddr_in *record1;
            record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in*));
            memset(record1, 0, 14);
            record1->a = 16;
            record1->b = 4;
            //strcpy(record1->sin_zero, "1");
            printf("Struct record1: %x", *record1);
        }

当我单独指定 record1-> a = 16 时,我得到“结构记录1:10

当我指定 record1-> a = 16 record1-> b = 4 时,我得到“结构记录1:40010 “(我可以发现它是Little Endianness,但仍然 *我的预期输出 04 10 * (短片各占两个字节))

当我指定 record1-> a = 16; * record1-> b = 4; * record1-> c.s_addr = 1UL ; * strcpy(record1-> d,“1”); *     输出仍然是“结构记录1:40010 ”( Y是对long的赋值而char []未反映?

任何人都可以解释这种行为。 我想看看结构的内容是如何在内存中分配的。有没有更智能的方法来实现这一目标?

3 个答案:

答案 0 :(得分:3)

您为指针的大小分配空间,而不是struct sockaddr_in的大小。因此,您将超出分配边界并进入未定义的行为。

尝试:

record1 = malloc(sizeof(*record));

其次,如果要打印短片,则打印短片。考虑到你发送一个指针 - 取消引用(即一个struct-val)作为hex-int打印,我甚至对你的printf感到震惊,甚至工作。如果您正在尝试打印字节,则需要使用枚举算法来执行此操作。

unsigned char *p = (unsigned char*)record1;
for (size_t i=0; i<sizeof(*record1); ++i)
    printf("%.2x ", p[i]);

是你可以这样做的一种方式。通过发布的main()中的设置,可以生成:

10 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 

这当然有道理。 a为16,而两字节短路中的little-endian确实为10 00。同样,b为4,同样,一个双字节无符号短,相同的小端,为04 00

答案 1 :(得分:2)

ashort,通常为2个字节长,b为unsigned short,通常也为2个字节长。 %x(printf样式格式化)中的一个字节长度为两个ASCII字符,因此2个字节长度为4个ASCII字符(使用%x打印时)。因此,ab一起最多可包含8个ASCII字符。无论如何,你打印结构内容的方式并不正确......你应该打印每个成员:

    struct in_addr {
        unsigned long s_addr;  // load with inet_aton()
    };

    struct sockaddr_in {
        short            a;
        unsigned short   b;
        struct in_addr   c;
        char             d[8];
    };

    int main(int argc, char** argv) {

        struct sockaddr_in *record1;
//      record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in*));
        record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
        memset(record1, 0, 14);
        record1->a = 16;
        record1->b = 4;
        //strcpy(record1->sin_zero, "1");
        printf("Struct record1:\n");
        printf("    a = 0x%04x\n", record1->a);
        printf("    b = 0x%04x\n", record1->b);
        printf("    c.s_addr = 0x%08x\n", record1->c.s_addr);
        printf("    d = %02x %02x %02x %02x %02x %02x %02x %02x\n",
               record1->d[0], record1->d[1], record1->d[2], record1->d[3],
               record1->d[4], record1->d[5], record1->d[6], record1->d[7]);
    }

答案 2 :(得分:0)

看着:

record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in*));

它可能不会做你想要的。您可能打算分配内存来保存sockaddr_in结构。该语句将为指针分配大小的内存为sockaddr_in。

正确的形式是(请注意,sizeof中的*已消失)

record1 = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));

现在它分配了正确的内存量。

在打印行中,你不能直接打印一个结构,你需要自己做一些艰苦的工作,

printf("Struct record1: %x %x %x %s", record1->a, record1->b, record->c.saddr, record1->d);

要将指针打印到record1,请使用类似的内容(注意*已经消失 - 您要打印指针,而不是它指向的指针)

printf("Struct record1: %x", record1);

如果要查看内存布局,可以使用类似

的内容
char* address;
for (address = record1 ; address < (record1+sizeof(sockaddr_in)) ; address++)
{
    printf("Address: %x  Contents: %x\n", address, *address);
}

还有一件事,更喜欢使用sizeof()而不是“14”:

memset(record1, 0, sizeof(sockaddr_in));