簡體   English   中英

在C中的鏈表中為新元素分配內存

[英]Allocating memory for new element in linked list in C

我正在嘗試創建一個鏈表,它已經起作用了,但是我仍然有些困惑。 我正在使用以下結構:

typedef struct _MList
{
    int dx;
    int dy;
    struct _MList *next;
} MList_t, *MList_p;

我已經測試過這種結構是否合理,並且我有一個函數可以打印出一個列表:

void mListPrint(MList_t *mList)
{
    MList_p node = mList;
    while (node->next != NULL)
    {
        printf("[%i,%i] ",node->dx,node->dy);
        node = node->next;
    }
    printf("[%i,%i]\n",node->dx,node->dy);
}

和創建第一個節點的函數:

MList_t mListNew(int dx, int dy)
{
    MList_t newNode;
    newNode.dx = dx;
    newNode.dy = dy;
    newNode.next = NULL;    
    return newNode;
}

有了這個良好的工作,我想我會嘗試制作一個在列表末尾添加一個節點的函數。 我的第一次嘗試是:

void mListAdd(int dx, int dy, MList_t *mList)
{
    MList_p node = mList;

    while (node->next != NULL)
    {
        node = node->next;  
    }

    MList_t newNode = mListNew(dx,dy);
    node->next = &newNode;
}

看起來不錯,直到我添加了多個元素。 經過大量調試后,事實證明,在mListAdd中創建的“ newNode”的內存地址始終相同。 因此,列表最終又鏈接回自身。 為什么是這樣?

我改為通過使用指向新節點的指針來實現mListAdd,如下所示:

void mListAdd(int dx, int dy, MList_t *mList)
{
    MList_p node = mList;

    while (node->next != NULL)
    {
        node = node->next;
    }
    MList_p newNode = malloc(sizeof(MList_t));
    *newNode = mListNew(dx,dy);
    mListPrint(newNode);
    node->next = newNode;
}

這很完美,但是我覺得另一種方法也應該起作用。 還是我缺少明顯的東西? 我正在嘗試通過實現我在Java和ML中學習的不同數據結構來學習C進行面試。

我對代碼的數量感到抱歉,但是我認為最好盡可能徹底地解釋我的問題。 謝謝您的提前幫助!

mListNew您正在使用局部變量:

MList_t newNode;

從函數返回后,這將超出范圍。 因此,您處於未定義的領域。 該代碼似乎僅在起作用,因為內存管理器不會覆蓋該局部變量占用的內存塊。

您應該在mListNew內使用malloc分配新的列表節點,並返回指向新節點的指針,如下所示:

MList_p mListNew(int dx, int dy)
{
    MList_p newNode = malloc(sizeof(MList_t));
    newNode->dx = dx;
    newNode->dy = dy;
    newNode->next = NULL;    
    return newNode;
}

第一個示例在堆棧上分配內存,因此它僅在函數內部時可用,因此您不應在可能無法在函數外部使用的鏈表中使用其內存地址。

抱歉,我敢肯定還有更多,但是我沒有讀過“還有一個用於創建第一個節點的函數”

MList_t mListNew(int dx, int dy)
{
    MList_t newNode;
    newNode.dx = dx;
    newNode.dy = dy;
    newNode.next = NULL;    
    return newNode;
}

newNode在堆棧上創建。 它的定義在函數mListNew()的本地,返回時為“未定義”。

最佳做法是您要求調用者在調用之前分配(和釋放)內存。 例如,

void mListNew(int dx, int dy, MList_t *newNode)
{
    newNode->dx = dx;
    newNode->dy = dy;
    newNode->next = NULL;    
}

我還沒有看剩下的...

您必須使用malloc()或calloc()顯式分配內存。 您要做的是使用僅存在於堆棧中的結構,而在mListAdd返回之后實際上不再存在。 碰巧它還沒有被覆蓋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM