指向指针的指针不会使它们相等

时间:2015-03-18 09:38:24

标签: c++ pointers hashmap

我有一个关于unicode代码点描述的大型静态哈希映射。每个散列值都会导致以null结尾的元素指针数组。以下是我的访问功能:

extern CodepointInfo ***codepoint_table;

uint32_t fnv1a(uint32_t input) { ... } // hash function

const CodepointInfo CodepointInfo::get(uint32_t codepoint) {
    uint32_t hash = fnv1a(codepoint) % 30000 // Number of buckets of the hashmap
    CodepointInfo **bucket = codepoint_table[hash];
    for(uint32_t i = 0; bucket[i] != nullptr; i++) {
            if(bucket[i]->codepoint == codepoint)
                    return *(codepoint_table[hash][i]);
    }
    return {codepoint, "unassigned", GeneralCategory::UNASSIGNED, 0, BidiClass::L, DecompositionType::NONE, nullptr, -1, nullptr, false, 0, 0, 0};
}

现在当我尝试使用它时,我遇到了一个段错误,所以我开始用gdb调试它并得到以下输出:

Breakpoint 1, nsucs::CodepointInfo::get (codepoint=0) at /home/richard/src/libnsucs/lib/codepoint_info.cc:21
21      uint32_t hash = fnv1a(codepoint) % NSUCS_CODEPOINTTABLE_NUM_BUCKETS;
(gdb) n
22      CodepointInfo **bucket = codepoint_table[hash];
(gdb) n
23      for(uint32_t i = 0; bucket[i] != nullptr; i++) {
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78cbd44 in nsucs::CodepointInfo::get (codepoint=0) at /home/richard/src/libnsucs/lib/codepoint_info.cc:23
23      for(uint32_t i = 0; bucket[i] != nullptr; i++) {
(gdb) print hash
$1 = 18805
(gdb) print codepoint_table[hash]
$2 = (nsucs::CodepointInfo **) 0x7ffff7d61d00 <nsucs::codepoint_table_fragment_18805>
(gdb) print bucket
$3 = (nsucs::CodepointInfo **) 0x0

在将一个分配给另一个之后,codepoint_table[hash]bucket是否应该相等?当我将bucket的用法替换为codepoint_table[hash]时,它仍然是段错误,但gdb中的print codepoint_table[hash][i]会产生正确的结果。

这里发生了什么?二进制文件根本没有优化。

编辑:

CodepointInfo结构的定义:

struct CodepointInfo {
    static const CodepointInfo get(uint32_t codepoint);

    uint32_t codepoint;
    const char *name;
    uint32_t general_category;
    uint8_t canonical_combining_class;
    BidiClass::Enum bidi_class;
    DecompositionType::Enum decomposition_type;
    uint32_t *decomposition_mapping;
    int8_t decimal_value;
    const char *numeric_value;
    bool bidi_mirrored;
    uint32_t simple_uppercase_mapping;
    uint32_t simple_lowercase_mapping;
    uint32_t simple_titlecase_mapping;
};

1 个答案:

答案 0 :(得分:0)

通过将extern CodepointInfo ***codepoint_table;更改为extern CodepointInfo **codepoint_table[];来修复它,该{{1}}与外部编译单元中的声明相匹配。

仍然不知道为什么会导致错误的任务行为。