這個作業的點是由含有城市狀態,接着由包含緯度和經度座標兩行的文件在一個要讀取行。然後我們需要動態分配結構,就像下面寫的那樣來存儲這些座標。最後,我們將地標導出爲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故障向上移動。