为什么我的变量值随机变化?

时间:2014-09-25 14:33:47

标签: c hashtable access-violation

我是C编程的新手,我最近才开始学习数据结构和算法。我选择的教科书是数据结构和C 中的算法分析,它引入了第5章中的哈希表ADT。这是其四开放寻址版本的一个实现,其中函数查找 Key TableSize 的值传递给 Hash < / strong> function它会将散列值作为变量 CurrentPos 返回。以下是功能哈希查找

Index
Hash( ElementType Key, int TableSize )
{
    return Key % TableSize;
}

Position
Find(ElementType Key, HashTable H)
{
    Position CurrentPos;
    int CollisionNum;

    CollisionNum = 0;
    CurrentPos = Hash(Key, H->TableSize);
    while(H->TheCells[CurrentPos].Info != Empty && H->TheCells[CurrentPos].Element != Key)
    {
        CurrentPos += 2 * ++CollisionNum - 1;
        if(CurrentPos >= H->TableSize)
            CurrentPos -= H->TableSize;
    }
    return CurrentPos;
}

这是标题:

    typedef int ElementType;
    #ifndef _HashQuad_H
    #define _HashQuad_H

    typedef unsigned int Index;
    typedef Index Position;

    struct HashTbl;
    typedef struct HashTbl *HashTable;

    HashTable InitializeTable( int TableSize );
    void DestroyTable( HashTable H );
    Position Find( ElementType Key, HashTable H );
    void Insert( ElementType Key, HashTable H );
    ElementType Retrieve( Position P, HashTable H );
    HashTable Rehash( HashTable H );

    #endif 

以下是源文件中的typedef和结构:

    struct HashEntry
    {
        ElementType      Element;
        enum KindOfEntry Info;
    };

    typedef struct HashEntry Cell;

    /* Cell *TheCells will be an array of */
    /* HashEntry cells, allocated later */
    struct HashTbl
    {
        int TableSize;
        Cell *TheCells;
    };

这是H被初始化的方式

    HashTable
    InitializeTable( int TableSize )
    {
        HashTable H;
        int i;

    if( TableSize < MinTableSize )
        {
            Error( "Table size too small" );
            return NULL;
        }

        /* Allocate table */
        H = malloc( sizeof( struct HashTbl ) );
        if( H == NULL )
            FatalError( "Out of space!!!" );

        H->TableSize = NextPrime( TableSize );

        /* Allocate array of Cells */
        H->TheCells = malloc( sizeof( Cell ) * H->TableSize );
        if( H->TheCells == NULL )
            FatalError( "Out of space!!!" );

        for( i = 0; i < H->TableSize; i++ )
            H->TheCells[ i ].Info = Empty;

        return H;
    }

现在问题是,但是这种实现在大多数情况下都能正常工作。它有时会遇到崩溃。当它发生时,我尝试单元测试并发现在某一轮调用哈希函数后, CurrentPos 的值将被指定为一个更大的整数比哈希函数的实际返回值,它可能是1000加甚至更大。 例如,如果 Key 为29918且 TableSize 为101,那么正确答案和是哈希返回的值为22,但是在分配之后行:

 CurrentPos = Hash(Key, H->TableSize);

CurrentPos 的值无论如何都会自行变为1580。 请注意,基于函数 time()的种子使用 rand()随机分配的 Key 值小于上限类型整数的边界 - 我的意思是应该没有溢出。

我努力寻找手表,但没有其他错误或线索。我很困惑,因为这个错误实际上是随机发生的。有没有人熟悉这个?

1 个答案:

答案 0 :(得分:2)

如果CollisionNum变得足够大,那么此测试将无法正常运行:

       if(CurrentPos >= H->TableSize)
            CurrentPos -= H->TableSize;

因为如果CurrentPos >= H->TableSize*2 CurrentPos,则H->TableSize减去 while (CurrentPos >= H->TableSize) CurrentPos -= H->TableSize; 之后仍会超出范围。

您应该将其更改为:

       CurrentPos = CurrentPos % H->TableSize;

或:

       CurrentPos %= H->TableSize;

甚至:

{{1}}