[英]I implemented a Map object in C, but using it gives me a Segmentation Fault
下面,我在C語言中定義了一個Map
結構。它通過setValue
和getValue
函數用作映射。 鍵值默認為-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;
}
(為什么不呢? thisIndex
比map[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.