如何用特定值填充非紧凑结构的所有填充字节?

时间:2019-03-19 08:21:51

标签: c

我们知道,由于对齐原因,结构可以具有内部填充字节。

如何用特定值填充非紧凑结构的所有填充字节?换句话说,请考虑以下代码段:

struct Foo;

// Is that possible to implement pad_Foo() function? If Yes, How?
void pad_Foo(struct Foo *pFoo_x, char pad_byte);

void bar(struct Foo *pFoo_x, int fd, char pad_byte)
{
    // reading in *pFoo_x from a file.
    // It may get some garbage padding bytes.
    read(fd, pFoo_x, sizeof(struct Foo));

    pad_Foo(&x, pad_byte);
}

是否可以实现pad_Foo()函数,如果答案是肯定的,怎么办?

1 个答案:

答案 0 :(得分:1)

  

是否可以实现pad_Foo()函数

作为符合标准的代码,答案为

根据C11草案n1570,6.2.6类型表示:

  

6当值存储在结构或联合类型的对象中(包括成员对象中)时,与任何填充字节对应的对象表示形式的字节采用未指定的值。 51)

  

51)因此,例如,结构分配不需要复制任何填充位。

因此标准明确指出:填充的值无法控制。

在特定系统(平台,操作系统,编译器)上,这是可能的。以我的系统为例:

# include <stdio.h>
# include <string.h>

struct s
{
  char c;
  int n;
};

void dump_struct(struct s * p)
{
  unsigned char * u = (unsigned char *)p;
  for (size_t i=0; i < sizeof *p; ++i) printf("%02x ", u[i]);
  printf("\n");
}

int main(){
  printf("sizeof(struct s)=%zu sizeof(char)=%zu sizeof(int)=%zu padding=%zu\n",
         sizeof(struct s), 
         sizeof(char), 
         sizeof(int), 
         sizeof(struct s) - sizeof(char) - sizeof(int));

  struct s sa;
  memset(&sa, 'A', sizeof sa);
  sa.c = '8';
  sa.n = 42;
  dump_struct(&sa);

  struct s sb;
  memset(&sb, 'B', sizeof sa);
  sb.c = '8';
  sb.n = 42;
  dump_struct(&sb);
}

输出:

sizeof(struct s)=8 sizeof(char)=1 sizeof(int)=4 padding=3
38 41 41 41 2a 00 00 00
38 42 42 42 2a 00 00 00
   ^^^^^^^^
    notice

因此,在我的系统上,memset确实写入了填充字节,但是在其他系统上,您可能会看到不同的行为。

将这样的代码添加到main

  unsigned char * u = (unsigned char *)&sb.c;
  u += sizeof sb.c;
  while(u < (unsigned char *)&sb.n)
  {
    *u = 'C';
    ++u;
  }
  dump_struct(&sb);

将打印多余的行:

38 43 43 43 2a 00 00 00

再次-在我的特定系统上-填充已更改。