2017-02-13 62 views
0

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

回答

0

在做指針運算,你沒有規模由sizeof(struct landmark_t)偏移 - 編譯器已經不適合您!

如果有一個指針p到一個數組,下一個數組元素是在p + 1。就這麼簡單。

此外,你似乎創建一個數組的記錄,當你應該創建一個記錄數組。但這是一個不同的問題。