В чем проблема с mapPut? Я не могу найти проблему - PullRequest
0 голосов
/ 24 апреля 2019

карта содержит - возвращает, существует ли ключ внутри карты.

mapPut - Дает определенному ключу заданное значение и добавляет его на карту по порядку. Если ключ существует, значение переопределяется. mapRemove - удаляет пару элементов (ключ, данные), для которых ключ соответствует заданному элементу (с помощью функции сравнения ключей).

mapGetFirst - устанавливает для внутреннего итератора первый ключ на карте и возвращает его.

MapKeyElement mapGetFirst(Map map){
if(map == NULL){
    return NULL;
}
if (map->head == NULL){
    return NULL;
}
map->iterator = map->head;
return (map->copyMapKeyElements(map->iterator->key));
}

mapGetNext - переводит внутренний итератор к следующему ключу и возвращает его.

MapKeyElement mapGetNext(Map map){

if(map == NULL){
    return NULL;
}

if((map->iterator->next)== NULL) {
    return NULL;
}
map->iterator = map->iterator->next;
return (map->copyMapKeyElements(map->iterator->key));
} 

typedef struct MapElements_t{

   MapDataElement data;
   MapKeyElement key;
   struct MapElements_t* next;
 } *MapElements;

struct Map_t{
   copyMapDataElements copyMapDataElements;
   copyMapKeyElements copyMapKeyElements;
   freeMapDataElements freeMapDataElements;
   freeMapKeyElements freeMapKeyElements;
   compareMapKeyElements compareMapKeyElements;
   MapElements head;
   MapElements iterator;
 };

  /* ...... */

MapResult mapPut(Map map, MapKeyElement keyElement, MapDataElement dataElement) {

    if ((map == NULL) || (keyElement == NULL) || (dataElement == NULL)) {
        return MAP_NULL_ARGUMENT;
    }
    if (mapContains(map, keyElement)) {
        mapRemove(map, keyElement);
    }
    MapElements new_map_element = malloc(sizeof(new_map_element));
    if (new_map_element == NULL) {
        return MAP_OUT_OF_MEMORY;
    }
    new_map_element->data = dataElement;
    new_map_element->key = keyElement;
    new_map_element->next = NULL;

    if(map->head == NULL){
        map->head = new_map_element;
        map->iterator = map->head;
        return MAP_SUCCESS;
    }

    mapGetFirst(map);
    if (map->compareMapKeyElements(keyElement, map->iterator->key) < 0){
        new_map_element->next = map->iterator;
        map->head = new_map_element;
        return MAP_SUCCESS;
    }

    while(map->iterator->next != NULL) {
        if (map->compareMapKeyElements(keyElement, map->iterator->next->key) < 0) {
            new_map_element->next = map->iterator->next;
            map->iterator = new_map_element;
            return MAP_SUCCESS;
        }
        mapGetNext(map);
    }

    map->iterator->next = new_map_element;
    return MAP_SUCCESS;
}

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

У вас есть typedefs, которые включают указатель, например typedef struct MapElements_t{...} *MapElements;, который делает тип MapElements указателем.

Это не рекомендуется и по следующей причине:

Когда вы делаете

MapElements new_map_element = malloc(sizeof(new_map_element));

, вы выделяете размер указателя, а не размер объекта, на который указывает.В вашем случае вы должны сделать:

MapElements new_map_element = malloc(sizeof(*new_map_element));

, но желательно, чтобы вы сделали:

typedef struct MapElements_t
{
    //...
   struct MapElements_t* next;
} MapElements;

, чтобы вы сделали переменную, которая является указателем на объект, который явно имеет *.

MapElements *new_map_element = malloc(sizeof(*new_map_element));
0 голосов
/ 25 апреля 2019

Ошибка была здесь; Я должен заменить этот код:

new_map_element->data = dataElement;
new_map_element->key = keyElement;

с этим кодом:

new_map_element->data = map->copyMapDataElements(dataElement);
new_map_element->key = map->copyMapKeyElements(keyElement);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...