[英]What is this line of C code doing for a hash map implementation?
At work we have been trying to figure out what this code does, and we feel like it could cause problems. 在工作中,我们一直在尝试弄清楚这段代码的作用,并且我们认为它可能会引起问题。 This is a hashmap implementation in C.
这是C语言中的hashmap实现。
static thrift_map_node_t *thrift_map_newnode (thrift_map_base_t *m, union keyDataTypes key, void * value, int vsize)
thrift_map_node_t *node;
int ksize = strlen(key) + 1;
int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
node = malloc(sizeof(*node) + voffset + vsize);
if (!node) return NULL;
memcpy(node + 1, key, ksize);
node->hash = thrift_hash(key);
node->value = ((char*) (node + 1)) + voffset;
memcpy(node->value, value, vsize);
return node;
The problem we think is here 我们认为的问题在这里
int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
We think this could produce a negative value, eg -9 % 4 = -1 in C. 我们认为这可能会产生负值,例如C中的-9%4 = -1。
a work around or any help to what this is attempting to do would be nice. 解决这个问题或对此做任何帮助都是很好的。
No, it cannot ever produce a negative value if size_t
has rank higher than or equal to int
(and it does except perhaps on some really oddish 16-bit addressing system with 32-bit integers), because then 不, 如果
size_t
秩高于或等于int
,它就永远不会产生负值(而且它可能在某些具有32位整数的真正奇怪的16位寻址系统上除外),因为
sizeof (void*) - ksize
will be of type size_t
that is an unsigned type and always positive. 将为
size_t
类型,该类型为无符号类型,并且始终为正。 Hence if void pointer is 8 bytes wide and ksize is 17, the result of subtraction is (size_t)-9
, or 18446744073709551607 on a 64-bit machine. 因此,如果void指针的宽度为8个字节,而ksize的值为17,则在64位计算机上,相减的结果为
(size_t)-9
或18446744073709551607。 That modulo 8 is 7, which added to 17 will result in 24, which is a multiple of sizeof (void *)
. 该模8为7,将其加到17将得到24,这是
sizeof (void *)
的倍数。
However, this relies on the sizeof (void *)
being a power of 2 , hence it would still be better if you used 但是,这取决于
sizeof (void *)
是2的幂 ,因此,如果使用
sizeof (void*) - (ksize + sizeof (void*)) % sizeof (void *)
for the padding as this avoids the negative numbers altogether 用于填充,因为这完全避免了负数
It is true though that would the result subtraction be signed , since C99 the modulo would be always negative: (-3) % 4
is -3
for example. 确实可以对结果减法进行签名 ,因为C99的模数始终为负:
(-3) % 4
例如为-3
。
BTW, the code should not use sizeof (void *)
, but _Alignof (void *)
. 顺便说一句,代码不应使用
sizeof (void *)
,而应使用_Alignof (void *)
。
There is still one more dubious thing in the code. 代码中还有另外一件事值得怀疑。 Suppose someone can actually feed in a string that is over 2 GiB in length - then a signed overflow occurs on majority of platforms and that is not going to be pretty!
假设某人实际上可以输入长度超过2 GiB的字符串-那么在大多数平台上都会发生有符号溢出,而且看起来不会很漂亮!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.