почему realloc вылетает из моей программы, когда я пытаюсь выделить новую память? - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть проблема с моей функцией realloc.у меня есть структура Country, и внутри у меня есть структура "City", которая включает в себя массив точек города, в котором каждый город имеет 3 поля:

typedef struct Country {
    char *name;
    int numberOfCities;
    City* cities;
    cordinate cordinateOfCountryLeft;
    cordinate cordinateOfCountryRight;
}Country;

typedef struct City
{
    char *name;
    char * popluarFood;
    int numberOfPeople;

}City;

Мне нужно удалить город из массива города, чтобы освободить городс функцией, которую я построил, называется freeCity:

void freeCity(City *pCity)
{
    free(pCity->name);
    free(pCity->popluarFood);
    free(pCity);
}

, но после удаления, когда я пытаюсь перераспределить, я получаю сообщение об ошибке в этой функции, когда realloc

status freeCityFromCountry(Country *country, char *cityName)
{
    for (int i = 0; i < country->numberOfCities; i++) {//for
        if (strcmp(country->cities[i].name, cityName)==0)
        {
           freeCity(country->cities+i);
            country->cities[i] = country->cities[country->numberOfCities - 1];
          //  free(country->cities[country->numberOfCities - 1]);
            country->cities = (City*)realloc(country->cities,(country->numberOfCities-1));
            country->numberOfCities--;
            return success;
        }
    }//for
    return failure;
}

, я малок страны-> города вдругая функция.где может быть проблема?спасибо

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Предполагая, что вы выделяете country->cities в другой функции.

Вы звоните freeCity(country->cities+i);

Но в функции freeCity вы также освобождаете город free(pCity);

Итак, для массива cities вы звоните бесплатно на city[i]. Это имеет две проблемы

  1. Для первого цикла, когда i равен 0, вы освобождаете массив, а затем перераспределяете его.
  2. Для других итераций, когда i не равен нулю, вы освобождаетесь в неправильном месте. Вы должны освободить основание массива, а не внутри массива.
0 голосов
/ 15 ноября 2018

Вы не можете вызвать free для указателя на середину выделенного чанка. country->cities указывает на непрерывный блок в памяти (N x sizeof(City)). Хорошее эмпирическое правило: если у вас malloc(something), вы должны иметь (и можете только иметь) free(something) где-то еще (malloc(country->cities) -> free(country->cities)).

Код вылетает из-за того, что первый вызов freeCity освобождает country->cities. Возможно, вы хотите, чтобы .cities был массивом указателей, то есть City**, в этом случае вы бы выделяли каждый City отдельно, а массив cities тогда указывал бы на фрагменты, которые вы можете освобождать по отдельности.

...