这个作业的点是由含有城市状态,接着由包含纬度和经度坐标两行的文件在一个要读取行。然后我们需要动态分配结构,就像下面写的那样来存储这些坐标。最后,我们将地标导出为Google地球使用的KML格式。ReAlloc如果包含结构的数组动态调整char指针
在这一点上,我可以正确地从我的结构写的KML。然而,在我的grow_whole函数中花了几个脏循环(见下文)。这个问题是我在后来释放所有分配的指针时。 (相信我,它存在虐待按顺序粘贴它)。我很确定问题是堆腐败。但是,我一直在这方面工作太久,我觉得它可能会更简单。
的文件格式。 (有像的这些150)
city, state
40 30 N
40 20 W
Wholesome_t只是将容纳在界标结构的量以及指针到第一地标信息的容器。 Landmark_t保存指向chars的指针,这些chars分配的空间量足以包含他们解析的城市名称等。
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分配和地标指针被设置为NULL。 然后我们为2个具有里程碑意义的结构指定malloc空间,并开始下面的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;
}
立刻while循环后,上面我们运行
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文件)但在tea_party我得到一个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-2在这里看到1-3的第一个结构,然后赛格故障之前)。
即使我尝试在seg故障之前打印land-> state,只是将seg故障向上移动。