结构成员正在采取错误的数据

时间:2011-10-26 17:28:40

标签: c

我编写了一个小程序来向您展示铸造问题

#include <stdlib.h>

struct flags {

    u_char flag1;
    u_char flag2;
    u_short flag3;
    u_char flag4;
    u_short flag5;

    u_char flag7[5];
};


int main(){

    char buffer[] = "\x01\x02\x04\x03\x05\x07\x06\xff\xff\xff\xff\xff";

    struct flags *flag;

    flag = (struct flags *) buffer;

    return 0;
}

我的问题是当我强制转换标志5时,错误地取“\ x06 \ xff”字节忽略“\ x07”而标志7错误地接受下一个4“\ xff”字节加上一个nul,这是下一个字节我也运行gdb

(gdb) p/x flag->flag5 
$1 = 0xff06
(gdb) p/x flag->flag7 
$2 = {0xff, 0xff, 0xff, 0xff, 0x0}
(gdb) x/15xb flag
0xbffff53f: 0x01    0x02    0x04    0x03    0x05    0x07    0x06    0xff
0xbffff547: 0xff    0xff    0xff    0xff    0x00    0x00    0x8a

为什么会发生这种情况以及我如何才能正确处理? 感谢

5 个答案:

答案 0 :(得分:3)

看起来像结构成员对齐问题。除非您知道编译器如何打包结构成员,否则不应该假设这些成员在内存中的位置。

0x07明显丢失的原因是因为编译器可能正在对16位边界上的flag5成员进行对齐,跳过保存0x07值的奇数内存位置。该值在填充中丢失。此外,你正在做的是溢出缓冲区,一个很大的禁忌。换句话说:

struct flags { 
    u_char flag1;    // 0x01
    u_char flag2;    // 0x02
    u_short flag3;   // 0x04 0x03
    u_char flag4;    // 0x05
    // 0x07 is in the padding
    u_short flag5;   // 0x06 0xff 
    u_char flag7[5]; // 0xff 0xff 0xff 0xff ... oops, buffer overrun, because your
                     // buffer was less than the sizeof(flags)
}; 

您通常可以使用大多数编译器控制结构成员的打包,但该机制是特定于编译器的。

答案 1 :(得分:2)

编译器可以自由地在结构的成员之间放置一些未使用的填充(例如)将对齐安排到它的会议中。您的编译器可能会提供#pragma packed或命令行参数,以确保紧密的结构打包。

答案 2 :(得分:0)

如何存储结构是实现定义的,因此,您不能依赖特定的内存布局来进行序列化。

要将结构序列化为字节数组,请编写一个按设定顺序序列化每个字段的函数。

答案 3 :(得分:0)

您可能需要pack the struct

struct flags __attribute__ ((__packed__)) {

    u_char flag1;
    u_char flag2;
    u_short flag3;
    u_char flag4;
    u_short flag5;

    u_char flag7[5];
};

注意:这是GCC - 我不知道它有多便携。

答案 4 :(得分:0)

这与填充有关。编译器正在为您的struct添加垃圾内存,以使其与您的内存正确对齐以提高效率。

请参阅以下示例:

http://msdn.microsoft.com/en-us/library/71kf49f1(v=vs.80).aspx
http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86