您还可以考虑使用助手功能。
请参见提交45ccef8,提交60566cb(由René Scharfe(rscharfe
)于2016年9月25日创建)。
(由Junio C Hamano -- gitster
--在提交b1f0a85中合并,于2016年10月3日)
它使用
COPY_ARRAY
,一个安全方便的助手来复制数组,补充
ALLOC_ARRAY
和
REALLOC_ARRAY
。
因此,您可以使用
COPY_ARRAY(temp, a, 1);
代替
memcpy(temp, a, sizeof(a));
。
用户只需指定源、目标和元素数量;元素大小会自动推断。
它检查大小和元素数量的乘积是否溢出。推断出的大小首先传递给
st_mult
,允许在编译时进行除法运算。
作为基本类型安全检查,它确保源和目标元素的大小相同。这也是在编译时评估的。
COPY_ARRAY
用于初始化数组时,如果要复制 0 个元素,则可以安全地将源指针设置为
NULL
。
在某些情况下,
原始的 memcpy(3)
不支持它——编译器可以假设只有有效的指针传递给它,并且可以在此类调用后优化掉
NULL
检查。
#define COPY_ARRAY(dst, src, n) copy_array((dst), (src), (n), sizeof(*(dst)) + \
BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))
static inline void copy_array(void *dst, const void *src, size_t n, size_t size)
{
if (n)
memcpy(dst, src, st_mult(size, n));
}
它使用
宏BUILD_ASSERT_OR_ZERO
,作为一个表达式(其中
@cond
是必须为真的编译时条件),断言一个构建时依赖。
如果条件不为真或无法被编译器评估,则编译将失败。
#define BUILD_ASSERT_OR_ZERO(cond) \
(sizeof(char [1 - 2*!(cond)]) - 1)
例子:
#define foo_to_char(foo) \
((char *)(foo) \
+ BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))
引入了内联函数st_mult
,详见提交320d0b4
static inline size_t st_mult(size_t a, size_t b)
{
if (unsigned_mult_overflows(a, b))
die("size_t overflow: %"PRIuMAX" * %"PRIuMAX,
(uintmax_t)a, (uintmax_t)b);
return a * b;
}
st_mult
是检测size_t
溢出的辅助函数之一,其中包括unsigned_mult_overflows
。
对我们提供给xmalloc
等函数的size_t
变量进行计算可能很危险,因为整数溢出可能导致我们分配比我们意识到的要小得多的块。
我们已经有unsigned_add_overflows()
,但让我们添加unsigned_mult_overflows()
。
#define unsigned_mult_overflows(a, b) \
((a) && (b) > maximum_unsigned_value_of_type(a) / (a))
这里使用了maximum_unsigned_value_of_type
: 用于检测无符号溢出的辅助工具 (来自提交 1368f6)
表达式(a + b < a)
可以很好地检测无符号整数是否溢出,但更明确的方法是
unsigned_add_overflows(a, b)
可能更容易阅读。
定义这样一个宏,大致扩展为 ((a) < UINT_MAX - (b))
。
因为该扩展仅在sizeof()
表达式之外使用每个参数一次,
所以可以安全地用于具有副作用的参数。
(UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a)))
使用CHAR_BIT
表示char类型中的位数(与架构有关)
您可以在Git 2.23(2019年第三季度)中看到一个示例。
请参见提交921d49b,提交177fbab(2019年6月15日),由René Scharfe(rscharfe
)提交。
(由Junio C Hamano -- gitster
--在提交e8d2590中合并,于2019年7月9日)
使用COPY_ARRAY
来复制数组
将调用memcpy(3)
的代码转换为使用COPY_ARRAY
,这可以使代码更加简短和简单。
sizeof(temp)
表示一个指向int[3]
的指针的大小。 - Daniel Fischertemp = (arr_1*)malloc(sizeof(arr_1));
替换了memset。然后它就对我起作用了。 - Rasmi Ranjan Nayak