簡體   English   中英

我用C實現了一個Map對象,但是使用它給我帶來了Segmentation Fault

[英]I implemented a Map object in C, but using it gives me a Segmentation Fault

下面,我在C語言中定義了一個Map結構。它通過setValuegetValue函數用作映射。 鍵值默認為-1。

typedef struct {
    int key;
    int value;
} Index;

typedef Index Map[1000];



void initMap(Map *map)
{
    for (int i = 0; i < 1000; i++)
    {
        Index thisIndex = *map[i];
        thisIndex.key = -1;
        thisIndex.value = 0;
    }
}

int getValue(Map *map, int keyToGet)
{
    for (int i = 0; i < 1000; i++)
    {
        Index thisIndex = *map[i];
        if (thisIndex.key == keyToGet)
        {
            return thisIndex.value;
            break;
        }
    }
    return -1;
}

void setValue(Map *map, int keyToSet, int valueToSet)
{
    int set = 0;
    for (int i = 0; i < 1000; i++)
    {
        Index thisIndex = *map[i];
        if (thisIndex.key == keyToSet)
        {
            thisIndex.value = valueToSet;
            set = 1;
            break;
        }
    }

    if (set == 1)
        return;

    for (int i = 0; i < 1000; i++)
    {
        Index thisIndex = *map[i];
        if (thisIndex.key == -1)
        {
            thisIndex.key = keyToSet;
            thisIndex.value = valueToSet;
            break;
        }
    }
}

int findValue(Map *map, int valueToGet)
{
    for (int i = 0; i < 1000; i++)
    {
        Index thisIndex = *map[i];
        if (thisIndex.value == valueToGet)
            return thisIndex.key;
    }
    return -1;
}

在代碼中的某個點運行時,我得到一個SegFault,大概是用於訪問或嘗試覆蓋我沒有管轄權的內存。 我的問題是,這在哪里發生? 哪個功能可以做到這一點,在哪里? 我已經篩選了好幾次,但似乎找不到發生的地方。

您的代碼中有兩個主要錯誤。

首先,鍵入Def Map到數組。 這意味着當您具有如下功能原型時:

int getValue(Map *map, int keyToGet);

你真的得到像這樣的東西:

int getValue(Index (*map)[1000], int keyToGet);

在C語言中,使用了定義技巧,因此您應該像這樣訪問地圖元素:

Index thisIndex = (*map)[i];

您使用它的方式, *map[i]等效於*(map [i]),並且要求該數組是指向Index的1,000個指針的數組,而並非如此。

(*map)[i]語法很復雜,您不需要它。 由於您的Map是一個數組,因此它會衰減為指向其第一個元素的指針。 如果要修改元素,則無需將指針傳遞給數組。 將指針傳遞到第一個元素就足夠了,在您的情況下,它可以是以下任意一個:

int getValue(Map map, int keyToGet);
int getValue(Index map[], int keyToGet);
int getValue(Index *map, int keyToGet);

然后訪問數組的元素就是map[i]

可以修復細分錯誤的修復程序,但是不能解決地圖不起作用的事實。 當您分配給這樣的結構時:

Index thisIndex = map[i];

然后修改thisIndex ,您將不會修改map任何內容! 在這里, thisIndex是一個副本。 thisIndex超出范圍時,所有修改都將丟失。

您可以直接使用map

if (map[i].key == keyToSet) {
    map[i].value = valueToSet;
    return;
}

(為什么不呢? thisIndexmap[i] ),或者可以使thisIndex指向數組元素的指針:

Index *thisIndex = &map[i];

if (thisIndex->key == keyToSet) {
    thisIndex->value = valueToSet;
    return;
}

在這里,您可以通過指針訪問和修改map[i]的字段。

將數組隱藏在typedef中可能不是一個好主意。 也許一次您想將活動項的數量保持在陣列旁邊。 (這將使您的代碼更高效,因為在最壞的情況下不必遍歷所有1,000個項目。)在這種情況下,您可以將Map構造為具有1000個鍵/值對和一個計數的數組的結構。 然后,您必須將指針傳遞給struct類型,以便可以更新字段。 :)練習... :)

暫無
暫無

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

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