c - 为什么将我的 C 结构写入二进制文件会产生比结构包含更多的数据
问题描述
我正在尝试将复杂的 C 结构(包含结构的结构)写入二进制文件,但不知何故,它生成的数据多于结构包含的数据。这是我的代码:
代码清单 1:
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
typedef struct __pbi {
char pbi_first_entry[3];
char pbi_second_entry[8];
} PBI;
typedef struct __bpr {
short bpr_first_entry;
char bpr_second_entry;
short bpr_third_entry;
char bpr_fourth_entry;
short bpr_fifth_entry;
short bpr_sixth_entry;
char bpr_seventh_entry;
short bpr_eighth_entry;
} BPR;
typedef struct __combo {
PBI pbi;
BPR bpb;
} COMBO;
int main(int argc, char * argv[])
{
if(argc < 2)
{
printf("Usage : %s device\n", argv[0]);
}
int dst;
char buffer[512];
int writecount;
if((dst = open(argv[1], O_RDWR | O_CREAT)) == -1)
{
printf("Couldn't open file %s for writing : %s\n", argv[1], strerror(errno));
exit(EXIT_FAILURE);
}
COMBO combo;
memcpy(combo.pbi.pbi_first_entry, (char[]){0, 1, 2}, 3);
printf("sizeof(pbi_first_entry) = %d\n", sizeof(combo.pbi.pbi_first_entry));
memcpy(combo.pbi.pbi_second_entry, (char[]){1, 2, 3, 4, 5, 6, 7, 8}, 8);
printf("sizeof(pbi_second_entry) = %d\n", sizeof(combo.pbi.pbi_second_entry));
combo.bpb.bpr_first_entry = 0x0201;
printf("sizeof(bpr_first_entry) = %d\n", sizeof(combo.bpb.bpr_first_entry));
combo.bpb.bpr_second_entry = 1;
printf("sizeof(bpr_second_entry) = %d\n", sizeof(combo.bpb.bpr_second_entry));
combo.bpb.bpr_third_entry = 0x0201;
printf("sizeof(bpr_third_entry) = %d\n", sizeof(combo.bpb.bpr_third_entry));
combo.bpb.bpr_fourth_entry = 1;
printf("sizeof(bpr_fourth_entry) = %d\n", sizeof(combo.bpb.bpr_fourth_entry));
combo.bpb.bpr_fifth_entry = 0x0201;
printf("sizeof(bpr_fifth_entry) = %d\n", sizeof(combo.bpb.bpr_fifth_entry));
combo.bpb.bpr_sixth_entry = 0x0B0A;
printf("sizeof(bpr_sixth_entry) = %d\n", sizeof(combo.bpb.bpr_sixth_entry));
combo.bpb.bpr_seventh_entry = 1;
printf("sizeof(bpr_seventh_entry) = %d\n", sizeof(combo.bpb.bpr_seventh_entry));
combo.bpb.bpr_eighth_entry = 0x0201;
printf("sizeof(bpr_eighth_entry) = %d\n", sizeof(combo.bpb.bpr_eighth_entry));
printf("sizeof(combo) = %d\n", sizeof(combo));
if((writecount = write(dst, &combo, sizeof(combo))) == -1)
{
printf("Failed to write the combo file : %s\n", strerror(errno));
exit(-5);
}
printf("Successfully wrote %d byte(s)!\n", writecount);
close(dst);
return(EXIT_SUCCESS);
}
当我编译并运行代码时,我得到以下输出:
输出清单 1:
sizeof(pbi_first_entry) = 3 sizeof(pbi_second_entry) = 8 sizeof(bpr_first_entry) = 2 sizeof(bpr_second_entry) = 1 sizeof(bpr_third_entry) = 2 sizeof(bpr_fourth_entry) = 1 sizeof(bpr_fifth_entry) = 2 sizeof(bpr_sixth_entry) = 2 sizeof(bpr_seventh_entry) = 1 sizeof(bpr_eighth_entry) = 2 sizeof(combo) = 28 Successfully wrote 28 byte(s)!
如果为每个条目添加 sizeof() 返回的值,它们将加起来为 24,但由于某种原因 sizeof(combo) 等于 28。combo 是整个结构。也因为 combo 在某种程度上等于 28 ;28 个字节被写入文件。
这是二进制文件的十六进制内容:
十六进制列表 1:
00 01 02 01 02 03 04 05 06 07 08 28 01 02 01 FF 01 02 01 28 01 02 0A 0B 01 B1 01 02
如你看到的 ; 直到第 11 个字节一切都很好,然后有一个字节的值等于0x28 ,然后一切都恢复正常,直到我们遇到另一个char
,然后是 ashort
并且它再次发生:我们从0x0201(short
)开始,然后是1(char
) 然后出现一个神秘的字节,其值为0xFF。每次遇到 achar
后跟 a时都会发生这种情况short
(0x28和0xB1作为神秘值)。
解决方案
推荐阅读
- php - 使用 laravel 社交名流验证用户的问题
- azure - 在 Log Analytics 查询中显示图表
- android - 错误:找不到正确的提供者
在此 Wrapper Widget 上方 - python - 怎么了?名称错误
- node.js - Azure AppService Kudu 部署在推送时失败
- html - CSS 样式不适用于 datetime-local 元素
- c++ - 如何在 Matlab MEX 文件中正确包含头 C++ 文件(来自 ALGLIB)
- c# - 在 C# 中使用查找模式
- c# - 如何使用 linq 对联接查询进行分组
- javascript - ReactJS useEffect() 每次页面加载时都会运行