【问题标题】:Array of Linked Lists C++链表数组 C++
【发布时间】:2014-02-20 15:32:25
【问题描述】:

所以我以为我理解了如何实现指针数组,但我的编译器却说不然 =(。任何帮助将不胜感激,我觉得我很接近但缺少一些关键的东西。

1.) 我声明了一个名为 node 的结构:。

struct node {

int num;

node *next;

}

2.) 我已经声明了一个指向指针数组的指针,如下所示:

node **arrayOfPointers;

3.) 然后我通过这样做动态地创建了指针数组:

arrayOfPointers = new node*[arraySize];

此时我的理解是,arrayOfPointers现在指向的是一个x节点类型的数组,其中x是=到arraySize。

4.) 但是当我想访问 arrayOfPointers 中的第五个元素以检查它的下一个指针是否为空时,我收到了分段错误错误。使用这个:

if (arrayOfPointers[5]->next == NULL)

{

cout << "I'm null" << endl;

}

有人知道为什么会这样吗?我可以通过以下方式为 num 赋值:arrayOfPointers[5]->num = 77;

但是我很困惑为什么检查结构中的指针会导致错误。此外,当我们这样做时,将 arrayOfPointers 传递给函数的正确原型是什么?它仍然是 (node **arrayOfPointers) 还是其他类似 (node * &arrayOfPointers) 的东西?

提前感谢您提供的任何提示或指示(哈哈)!

完整代码(更新):

 /*
* Functions related to separate chain hashing
*/

struct chainNode
{
    int value;
    chainNode *next;
};

chainNode* CreateNewChainNode (int keyValue)
{
    chainNode *newNode;

    newNode = new (nothrow) chainNode;

    newNode->value = keyValue;
    newNode->next = NULL;

    return newNode;
}


void InitDynamicArrayList (int tableSize, chainNode **chainListArray)
{

    // create dynamic array of pointers
    chainListArray = new (nothrow) chainNode*[tableSize];

    // allocate each pointer in array
    for (int i=0; i < tableSize; i++)
    {
        chainListArray[i]= CreateNewChainNode(0);
    }

    return;
}


bool SeparateChainInsert (int keyValue, int hashAddress, chainNode **chainListArray)
{
    bool isInserted = false;
    chainNode *newNode;

    newNode = CreateNewChainNode(keyValue);    // create new node

    // if memory allocation did not fail, insert new node into hash table
    if (newNode != NULL)
    {
        //if array cell at hash address is empty
        if (chainListArray[hashAddress]->next == NULL)
        {
            // insert new node to front of list, keeping next pointer still set to NULL
            chainListArray[hashAddress]->next = newNode;

        }
        else //else cell is pointing to a list of nodes already
        {
            // new node's next pointer will point to former front of linked list
            newNode->next = chainListArray[hashAddress]->next;

            // insert new node to front of list
            chainListArray[hashAddress]->next = newNode;

        }

        isInserted = true;
        cout << keyValue << " inserted into chainListArray at index " << hashAddress << endl;
    }

    return isInserted;
}

/*
* Functions to fill array with random numbers for hashing
*/

void FillNumArray (int randomArray[])
{
    int i = 0;                                  // counter for for loop
    int randomNum = 0;                          // randomly generated number

    for (i = 0; i < ARRAY_SIZE; i++)            // do this for entire array
    {
        randomNum = GenerateRandomNum();             // get a random number

        while(!IsUniqueNum(randomNum, randomArray))  // loops until random number is unique
        {
               randomNum = GenerateRandomNum();
        }

        randomArray[i] = randomNum;                  // insert random number into array
    }

    return;
}


int GenerateRandomNum ()
{
    int num = 0;                               // randomly generated number

    // generate random number between start and end ranges
    num = (rand() % END_RANGE) + START_RANGE;

    return num;
}

bool IsUniqueNum (int num, int randomArray[])
{
    bool isUnique = true;         // indicates if number is unique and NOT in array
    int index = 0;                // array index

        //loop until end of array or a zero is found
        //(since array elements were initialized to zero)
        while ((index < ARRAY_SIZE) && (!randomArray[index] == 0))
        {
            // if a value in the array matches the num passed in, num is not unique
            if (randomArray[index] == num)
            {
                isUnique = false;
            }

            index++;            // increment index counter

        }   // end while

    return isUnique;
}



/*
*main
*/

int main (int argc, char* argv[])
{
    int randomNums[ARRAY_SIZE] = {0};     // initialize array elements to 0
    int hashTableSize = 0;                // size of hash table to use
    chainNode **chainListArray;
    bool chainEntry = true;     //testing chain hashing

    //initialize random seed
    srand((unsigned)time(NULL));

    FillNumArray(randomNums);           // fill randomNums array with random numbers

    //test print array
    for(int i = 0; i < ARRAY_SIZE; i++)
    {
        cout << randomNums[i] << endl;
    }

    //test chain hashing insert
    hashTableSize = 19;
    int hashAddress = 0;

    InitDynamicArrayList(hashTableSize, chainListArray);

    //try to hash into hash table
    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        hashAddress = randomNums[i] % hashTableSize;
        chainEntry = SeparateChainInsert(randomNums[i], hashAddress, chainListArray);
    }


    system("pause");
    return 0;
}

【问题讨论】:

    标签: c++ arrays pointers data-structures linked-list


    【解决方案1】:
    arrayOfPointers = new node*[arraySize];
    

    这会返回一堆未分配的指针。你的顶级数组很好,但它的元素仍然是未初始化的指针,所以当你这样做时:

    ->next
    

    你调用了未定义的行为。您正在取消引用一个未初始化的指针。

    你正确分配了数组,现在你需要分配每个指针,即,

    for(int i = 0; i < arraySize; ++i) {
        arrayOfPointers[i] = new node;
    }
    

    顺便说一句,我意识到您正在学习,但您应该意识到您实际上是在这里编写 C。在 C++ 中,您有无数出色的数据结构可以为您处理内存分配(更重要的是,释放)。

    【讨论】:

    • 或者实际上,只需将它们全部设置为 NULL。这看起来像是某种哈希表。
    • 我已经按照建议分配了数组中的每个指针,但是当我尝试使用 arrayofpointers[x]->next 检查它是否为空时程序崩溃
    • @Ducksauce88:如果您正确分配了arrayofpointers[x]arrayofpointers[x]-&gt;next 就不会崩溃。向我们展示您的代码。
    • @Ducksauce88:在InitDynamicArrayList 内部,这是错误的:chainListArray = new (nothrow) chainNode*[tableSize];。 C++ 中的参数是按值传递的,即函数接收一个副本。如果您想为chainListArray 分配一个新值,那么您需要使用另一个间接级别,即ChainNode*** 并使用*chainListArray = new ...
    【解决方案2】:

    您的代码很好,但它与您声明 InitDynamicArrayList 的方式有关。一种方法是使用 ***chainListArray,或者更类似于 C++ 的语法来使用如下引用:

    void InitDynamicArrayList (int tableSize, chainNode **&chainListArray)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-26
      • 2011-04-28
      • 1970-01-01
      • 2018-01-01
      相关资源
      最近更新 更多