简体   繁体   中英

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.

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.

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

sizeof (void*) - ksize

will be of type size_t that is an unsigned type and always positive. 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. That modulo 8 is 7, which added to 17 will result in 24, which is a multiple of 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*) - (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.

BTW, the code should not use sizeof (void *) , but _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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM