Точка этого назначения должна считываться в строке из файла, содержащего городское состояние, за которым следуют две строки, которые содержат координаты широты и долготы. Затем нам нужно динамически выделять структуры точно так, как они написаны ниже, чтобы сохранить эти координаты. Наконец, мы экспортируем ориентиры в формат KML, используемый Google Earth.Realloc массив структур, которые содержат указатели на указатели с динамическим размером
На этом этапе я могу правильно написать KML из своих структур. Однако это заняло пару грязных для петель в моей функции grow_whole (см. Ниже). Проблема в том, что я освобождаю все выделенные указатели позже. (Поверьте мне, он существует, плохо вставьте его в порядке ниже). Я уверен, что проблема заключается в коррупции кучи. Однако я работал слишком долго, и я чувствую, что это может быть проще.
Формат файла. (Существуют как 150 из них.)
city, state
40 30 N
40 20 W
Wholesome_t просто контейнер, который будет содержать информацию о количестве знаковых структур, а также указателе на первый ориентир. Landmark_t содержит указатели на символы, которые выделяются с таким количеством пространства, в котором они нуждаются, чтобы содержать их разное имя города и т. Д.
struct landmark_t {
char *city;
char *state;
char *country;
float longitude;
float latitude;
};
struct wholesome_t {
struct landmark_t *landmarks;
int landcount;
int landmax;
};
Ниже приведен фрагмент кода, который обрабатывает строки считывания и отправляет их в правильный синтаксический анализатор.
Первоначально здоровым является malloc'd, а указатель ориентиров установлен в NULL. Затем мы malloc-пространство для 2 ориентирных структур и начинаем цикл while ниже.
struct landmark_t *land = NULL;
int coorflag = 0;
int flagcount = 0;
//Parse lines
while(fgets(buf, LEN, in)){
//Does that thing where we realloc
if(whole->landcount == whole->landmax){
grow_whole(whole);
}
//remove trailing newline
buf[strcspn(buf, "\n")] = 0;
if(!coorflag){//Check to see if we are on a flag or coordinate
//set land to be the pointer to our next empty landmark struct
land = whole->landmarks + (sizeof(struct landmark_t) * whole->landcount);
set_city_state_country(buf, land);
coorflag = 1; //Set flag to get a coordinate line next
}else{//We are on a coordinate line which will use
//the same land struct pointer as above
if(!flagcount){//Have we seen a coordinate line already?
land->latitude = number_muncher(buf);
flagcount = 1;
}else{//We have seen a coordinate line
land->longitude = number_muncher(buf);
//We are done filling this structure. Reset flags and move to the next.
flagcount = 0;
coorflag = 0;
whole->landcount++;
}
}
}
Проблема в grow_whole. Раньше у меня была проблема, когда после запуска realloc первая наземная структура будет содержать правильно назначенные указатели, но что-нибудь после нее, пока где-нибудь ближе к концу файла все указатели на город, штат и страну, а также долготу и широту будут изгнан. Я добавил циклы for, которые сохраняют все наши указатели до массивов до того, как мы повторно выберем, а затем перепишем эти указатели обратно в правильную структуру.
void grow_whole(struct wholesome_t *whole)
{
//First collect all of the pointers inside our current landmark structs.
struct landmark_t *land = NULL;
char *city[whole->landcount];
char *state[whole->landcount];
char *country[whole->landcount];
float longitude[whole->landcount];
float latitude[whole->landcount];
for (int i = 0; i < whole->landcount; i++){
land = whole->landmarks + (sizeof(struct landmark_t) * i);
city[i] = land->city;
state[i] = land->state;
country[i] = land->country;
longitude[i] = land->longitude;
latitude[i] = land->latitude;
}
land = realloc(whole->landmarks, (GROW + whole->landmax) * sizeof(struct landmark_t));
if(land == NULL){
printf("Error in grow_whole.\n");
return;
}else{whole->landmarks = land;}
//Update landmax to represent aftergrow.
whole->landmax = GROW + whole->landmax;
//Refill all of the re allocated structs with their pointers.
for (int i = 0; i < whole->landcount; i++){
land = whole->landmarks + (sizeof(struct landmark_t) * i);
land->city = city[i];
land->state = state[i];
land->country = country[i];
land->longitude = longitude[i];
land->latitude = latitude[i];
}
//Fill two new structs with blank data.
for(int i = whole->landcount; i < whole->landmax; i++){
land = whole->landmarks + (sizeof(struct landmark_t) * i);
empty_fill(land);
}
return;
}
немедленно после цикла в то время как выше мы запускаем
fclose(in);
char *s = argv[1];
s = strtok(s, ".");
s = strncat(s, ".kml", 4);
FILE *out = fopen(s, "w");
//Finally done lets write some KML
kml_begin(out);
for (int i=0; i < whole->landcount; i++){
land = whole->landmarks + (sizeof(struct landmark_t) * i);
kml_placemark(out, i, land);
}
kml_end(out);
fclose(out);
tea_party(whole);//free land
free(whole->landmarks);
free(whole);
который получает в kml_end (уходит). (Я знаю, потому что я правильно отформатирован с правильными значениями .kml file) Но во время чаепития я получаю seg_fault.
void tea_party(struct wholesome_t *whole)
{
struct landmark_t *land = NULL;
for (int i = 0; i < whole->landcount; i++){
land = whole->landmarks + (sizeof(struct landmark_t) * i);
printf("here\n");
free(land->city);
printf("here2\n");
free(land->state);
printf("here3\n");
free(land->country);
}
return;
}
Это происходит для нашей второй ориентирной структуры.
land = whole->landmarks + sizeof(struct landmark_t)
А бывает при свободном (земле-> состояние) (потому что я вижу здесь 1-3 для первого и структура затем здесь 1-2 перед ошибкой SEG.)
Даже если я пытаюсь print land-> state right before seg fault, он просто перемещает сегрегацию.