- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在 C 中有以下方法来加载二进制文件,必须检查每个 fread
调用的错误值似乎相当冗长乏味,有没有更简洁的方法来处理这个问题?
我知道可以通过一次读取结构来减少一些调用,但由于 C 可以在结构成员之间添加填充字节,我宁愿避免这种情况。
some_type_t *load_something(FILE *file) {
some_type_t *something = (some_type_t *)malloc(sizeof(some_type_t));
if (something == NULL) {
return NULL;
}
if (fread(&something->field1, sizeof(something->field1), 1, file) == 0) {
free(something);
return NULL;
}
if (fread(&something->field2, sizeof(something->field2), 1, file) == 0) {
free(something);
return NULL;
}
if (fread(&something->field3, sizeof(something->field3), 1, file) == 0) {
free(something);
return NULL;
}
uint16_t some_var1, some_var2, some_var3;
some_other_type_t *something_else1 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
if (fread(&some_var1, sizeof(some_var1), 1, file) == 0) {
free(something);
free(something_else1);
return NULL;
}
some_other_type_t *something_else2 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
if (fread(&some_var2, sizeof(some_var2), 1, file) == 0) {
free(something);
free(something_else1);
free(something_else2);
return NULL;
}
some_other_type_t *something_else3 = (some_other_type_t *)malloc(sizeof(some_other_type_t));
if (fread(&some_var3, sizeof(some_var3), 1, file) == 0) {
free(something);
free(something_else1);
free(something_else2);
free(something_else3);
return NULL;
}
// Do something with the vars and allocated something elses.
// ...
return something;
}
最佳答案
为什么不创建一个宏:
#define READ_FIELD(data) \
do { if (fread(&data, sizeof(data), 1, file) == 0) { \
free(something); \
free(something_else1);
free(something_else2);
return NULL; \
} } while(0)
然后像函数调用一样调用它:
READ_FIELD(something->field1);
READ_FIELD(something->field2);
READ_FIELD(some_var1);
READ_FIELD(some_var2);
代码将是相同的,但至少它现在是生成的而不是复制/粘贴的(可能有错误)。
宏必须在所有可能的内存块上调用 free
,即使是那些尚未分配的内存块。唯一的约束是将未分配的设置为 NULL
,这样 free
就不会崩溃。并且要 super 安全地更改为:
free(something); something = NULL;
(当然,如果 something
是分配指针的副本,设置为 NULL
并不能防止双重释放,它有限制)
您也可以将此技术应用于写入端,并且由于 M Oehm 建议,您可以在包装器宏中列出要读取/写入的内容:
#define DO_ALL \
DO_FIELD(something->field1); \
DO_FIELD(something->field2); \
DO_FIELD(some_var1); \
DO_FIELD(some_var2)
然后将DO_FIELD
定义为READ_FIELD
或WRITE_FIELD
:
#define DO_FIELD READ_FIELD
DO_ALL;
#undef DO_FIELD
关于c - 处理来自多个 fread 调用的错误的更简洁的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45564424/
我正在用 C# 编写动态语言的解释器,并将原始函数实现为具有虚拟 Apply 方法的抽象类 Primitive,其中每个实际原始函数都是重写 Apply 的子类。 (另一种方法是只拥有类 Primit
我正在用 C# 编写动态语言的解释器,并将原始函数实现为具有虚拟 Apply 方法的抽象类 Primitive,其中每个实际原始函数都是重写 Apply 的子类。 (另一种方法是只拥有类 Primit
我是 Dapper 的新手我正在尝试了解它实际上是如何映射事物的。我有以下数据库结构: calendar | Id | Name | meeting_room | Id | Calendar_id
抱歉问题标题很糟糕。有没有办法在一行中做到这一点: Button button = (Button)Gridview.Cells[0].FindControl("controlname"); butt
在 Java 中在声明点和使用点声明列表/数组文字的tersest方法是什么? 作为次要问题,我更喜欢一种不会导致编译时警告或要求抑制警告的方法。 注意:就我个人而言,这是针对Java 8ish on
什么是现代、简洁、快速的方法来测试节点是否有任何与给定选择器匹配的子节点? “简洁”是指类似于 jQuery 或函数式风格,例如避免循环。我知道本地选择器越来越多地使用这种类型的东西,但没有跟上发展的
getFirstNotNullResult 执行函数列表,直到其中一个函数返回非空值。 如何更优雅/简洁地实现 getNotNullFirstResult? object A { def main
根据 stackoverflow 上某人的推荐,我使用了 jquery succint https://github.com/micjamking/Succinct截断我在 php 网站上的帖子。 它
我是一名优秀的程序员,十分优秀!