2

次のコードを使用して、ハッシュテーブルのテストに使用する「キー」を作成しています(特に、アイテムの削除に必要な時間をテストしています)。

void remove_keys()
{
    for (int i = 0; i < NUM_ITEMS; i++) {
        char temp_key[20];
        sprintf((char *)&temp_key, "Key: %d", i);
        size_t key_len = strlen(temp_key) + 1;


        char *key = malloc(sizeof(char) * (key_len));
        sprintf(key, "%s", temp_key); // THIS LINE

        htable_item *item = htable_item_search(root, key, key_len);
        if (!item) {
            printf("Item not found: %s\n", key);
        } else {
            //printf("Item found: %s - %s\n", key, item->value);
            if (!htable_item_delete(root, item)) {
                printf("Error while deleting: %s\n", key);
            }
        }
    }
}

コメントでマークした行には、奇妙な動作があります。sprintfを使用して「temp_key」の内容を「key」にコピーしています。その前に、strncpyを使用して「temp_key」の内容を「key」にコピーしましたが、この操作から得られた結果は次のとおりです(XCodeのデバッガーから出力)。

Printing description of key:
(char *) key = 0x0000000100103ed0 "Key: 10\xb0\xe7\x03\x01\x10"

一方、「temp_key」は次の出力を生成します。

Printing description of temp_key:
(char [20]) temp_key = "Key: 10" {
  [0] = 'K'
  [1] = 'e'
  [2] = 'y'
  [3] = ':'
  [4] = ' '
  [5] = '1'
  [6] = '0'
  [7] = '\0'
  [8] = '\0'
  [9] = '\0'
  [10] = '\0'
  [11] = '\0'
  [12] = '\0'
  [13] = '\0'
  [14] = '\0'
  [15] = '\0'
  [16] = '\0'
  [17] = '\0'
  [18] = '\0'
  [19] = '\0'
}

ハッシュテーブルはmemcmpを使用して、htable_item_search関数のキーを比較します。ただし、strncpyを使用すると、sprintfの使用中に見つからないアイテム(「Key:10」など)がいくつかあり、完全に機能します。では、なぜこの違いがあるのでしょうか。

4

1 に答える 1

3

http://www.cplusplus.com/reference/clibrary/cstring/strncpy/から

sourceがnumより長い場合、宛先の最後にnull文字が暗黙的に追加されることはありません(したがって、この場合、destinationはnullで終了するC文字列ではない可能性があります)。

strncpyは文字列にnullターミネータを追加しないため、この関数を使用している間、文字列の最後にゴミが残ります。

于 2012-11-18T11:24:57.833 に答える